./PaxHeaders.2978/edfbrowser_153_source0000644000175000001440000000013212251654530016227 xustar000000000000000030 mtime=1386699096.506032369 30 atime=1386699096.454032643 30 ctime=1386699096.506032369 edfbrowser_153_source/0000755000175000001440000000000012251654530015700 5ustar00novarausers00000000000000edfbrowser_153_source/PaxHeaders.2978/z_ratio_filter.cpp0000644000175000001440000000013212251654530021667 xustar000000000000000030 mtime=1386699096.479032511 30 atime=1386699096.479032511 30 ctime=1386699096.479032511 edfbrowser_153_source/z_ratio_filter.cpp0000644000175000001440000001410012251654530021414 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * The current version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "z_ratio_filter.h" #define ZRATIO_EPOCH_LEN 2 #define ZRATIO_F1 3.0 #define ZRATIO_F3 12.0 #define ZRATIO_F4 25.0 struct zratio_filter_settings * create_zratio_filter(int smp_per_record, long long long_data_record_duration, double crossoverf, double bitval) { struct zratio_filter_settings * settings; settings = (struct zratio_filter_settings *)calloc(1, sizeof(struct zratio_filter_settings)); if(settings == NULL) { return(NULL); } settings->crossoverfreq = crossoverf; settings->bitvalue = bitval; settings->dftblocksize = ((long long)smp_per_record * (ZRATIO_EPOCH_LEN * TIME_DIMENSION)) / long_data_record_duration; if(settings->dftblocksize < (ZRATIO_EPOCH_LEN * 100)) { free(settings); return(NULL); } settings->samplefreq = (double)smp_per_record / ((double)long_data_record_duration / TIME_DIMENSION); if(settings->samplefreq < 99.9999999) { free(settings); return(NULL); } settings->fft_outputbufsize = settings->dftblocksize / 2; settings->freqstep = settings->samplefreq / (double)settings->dftblocksize; if(settings->freqstep > 1.0001) { free(settings); return(NULL); } settings->f2 = settings->crossoverfreq / settings->freqstep; settings->f1 = ZRATIO_F1 / settings->freqstep; settings->f3 = ZRATIO_F3 / settings->freqstep; settings->f4 = ZRATIO_F4 / settings->freqstep; settings->fft_inputbuf = (double *)malloc(sizeof(double) * settings->dftblocksize); if(settings->fft_inputbuf == NULL) { free(settings); return(NULL); } settings->fft_inputbuf_bu = (double *)malloc(sizeof(double) * settings->dftblocksize); if(settings->fft_inputbuf_bu == NULL) { free(settings->fft_inputbuf); free(settings); return(NULL); } settings->fft_outputbuf = (double *)calloc(1, sizeof(double) * settings->fft_outputbufsize); if(settings->fft_outputbuf == NULL) { free(settings->fft_inputbuf); free(settings->fft_inputbuf_bu); free(settings); return(NULL); } settings->kiss_fftbuf = (kiss_fft_cpx *)malloc((settings->fft_outputbufsize + 1) * sizeof(kiss_fft_cpx)); if(settings->kiss_fftbuf == NULL) { free(settings->fft_inputbuf); free(settings->fft_inputbuf_bu); free(settings->fft_outputbuf); free(settings); return(NULL); } settings->cfg = kiss_fftr_alloc(settings->dftblocksize, 0, NULL, NULL); settings->smpls_in_inputbuf = 0; settings->zratio_value = 0.0; return(settings); } double run_zratio_filter(double new_sample, struct zratio_filter_settings *settings) { int i; double power_delta, power_theta, power_alpha, power_beta, power_total; settings->fft_inputbuf[settings->smpls_in_inputbuf++] = new_sample; if(settings->smpls_in_inputbuf >= settings->dftblocksize) { settings->smpls_in_inputbuf = 0; kiss_fftr(settings->cfg, settings->fft_inputbuf, settings->kiss_fftbuf); power_delta = 0.0; power_theta = 0.0; power_alpha = 0.0; power_beta = 0.0; power_total = 0.0; for(i=0; ifft_outputbufsize; i++) { settings->fft_outputbuf[i] = (((settings->kiss_fftbuf[i].r * settings->kiss_fftbuf[i].r) + (settings->kiss_fftbuf[i].i * settings->kiss_fftbuf[i].i)) / settings->fft_outputbufsize); if((i > 0) && (i < settings->f1)) { power_delta += settings->fft_outputbuf[i]; } if((i >= settings->f1) && (i < settings->f2)) { power_theta += settings->fft_outputbuf[i]; } if((i >= settings->f2) && (i < settings->f3)) { power_alpha += settings->fft_outputbuf[i]; } if((i >= settings->f3) && (i <= settings->f4)) { power_beta += settings->fft_outputbuf[i]; } power_total += settings->fft_outputbuf[i]; } if(power_total <= 0.0) { settings->zratio_value = 0.0; } else { settings->zratio_value = ((power_delta + power_theta) - (power_alpha + power_beta)) / power_total; } } return(settings->zratio_value / settings->bitvalue); } void zratio_filter_save_buf(struct zratio_filter_settings *settings) { settings->smpls_in_inputbuf_bu = settings->smpls_in_inputbuf; settings->zratio_value_bu = settings->zratio_value; memcpy(settings->fft_inputbuf_bu, settings->fft_inputbuf, settings->dftblocksize); } void zratio_filter_restore_buf(struct zratio_filter_settings *settings) { settings->smpls_in_inputbuf = settings->smpls_in_inputbuf_bu; settings->zratio_value = settings->zratio_value_bu; memcpy(settings->fft_inputbuf, settings->fft_inputbuf_bu, settings->dftblocksize); } void free_zratio_filter(struct zratio_filter_settings *settings) { free(settings->fft_inputbuf); free(settings->fft_inputbuf_bu); free(settings->fft_outputbuf); free(settings->kiss_fftbuf); free(settings->cfg); free(settings); } void reset_zratio_filter(struct zratio_filter_settings *settings) { settings->smpls_in_inputbuf = 0; settings->zratio_value = 0.0; } edfbrowser_153_source/PaxHeaders.2978/signal_chooser.h0000644000175000001440000000013212251654530021317 xustar000000000000000030 mtime=1386699096.468032569 30 atime=1386699096.468032569 30 ctime=1386699096.468032569 edfbrowser_153_source/signal_chooser.h0000644000175000001440000000427312251654530021056 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef SIGNAL_CHOOSERFORM1_H #define SIGNAL_CHOOSERFORM1_H #include #include #include #include #include #include #include #include #include "global.h" #include "mainwindow.h" #include "viewcurve.h" #include "adjustfiltersettings.h" #include "ecg_filter.h" #include "utils.h" class UI_Mainwindow; class ViewCurve; class UI_SignalChooser : public QObject { Q_OBJECT public: UI_SignalChooser(QWidget *, int, int *sgnl_nr = NULL); UI_Mainwindow *mainwindow; private: QDialog *signalchooser_dialog; QPushButton *CloseButton, *UpButton, *DownButton, *DeleteButton, *InvertButton; QListWidget *list; int task, *signal_nr; void strip_types_from_label(char *); void load_signalcomps(void); private slots: void call_sidemenu(QListWidgetItem *); void signalUp(); void signalDown(); void signalDelete(); void signalInvert(); }; #endif // SIGNAL_CHOOSERFORM1_H edfbrowser_153_source/PaxHeaders.2978/edflib.h0000644000175000001440000000013212251654530017545 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/edflib.h0000644000175000001440000007641512251654530017313 0ustar00novarausers00000000000000/* ***************************************************************************** * * Copyright (c) 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * All rights reserved. * * email: teuniz@gmail.com * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY Teunis van Beelen ''AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL Teunis van Beelen BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************** */ /* compile with options "-D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE" */ #ifndef EDFLIB_INCLUDED #define EDFLIB_INCLUDED #include #include #include #include #define EDFLIB_TIME_DIMENSION (10000000LL) #define EDFLIB_MAXSIGNALS 512 #define EDFLIB_MAX_ANNOTATION_LEN 512 #define EDFSEEK_SET 0 #define EDFSEEK_CUR 1 #define EDFSEEK_END 2 /* the following defines are used in the member "filetype" of the edf_hdr_struct */ /* and as return value for the function edfopen_file_readonly() */ #define EDFLIB_FILETYPE_EDF 0 #define EDFLIB_FILETYPE_EDFPLUS 1 #define EDFLIB_FILETYPE_BDF 2 #define EDFLIB_FILETYPE_BDFPLUS 3 #define EDFLIB_MALLOC_ERROR -1 #define EDFLIB_NO_SUCH_FILE_OR_DIRECTORY -2 #define EDFLIB_FILE_CONTAINS_FORMAT_ERRORS -3 #define EDFLIB_MAXFILES_REACHED -4 #define EDFLIB_FILE_READ_ERROR -5 #define EDFLIB_FILE_ALREADY_OPENED -6 #define EDFLIB_FILETYPE_ERROR -7 #define EDFLIB_FILE_WRITE_ERROR -8 #define EDFLIB_NUMBER_OF_SIGNALS_INVALID -9 #define EDFLIB_FILE_IS_DISCONTINUOUS -10 #define EDFLIB_INVALID_READ_ANNOTS_VALUE -11 /* values for annotations */ #define EDFLIB_DO_NOT_READ_ANNOTATIONS 0 #define EDFLIB_READ_ANNOTATIONS 1 #define EDFLIB_READ_ALL_ANNOTATIONS 2 /* the following defines are possible errors returned by edfopen_file_writeonly() */ #define EDFLIB_NO_SIGNALS -20 #define EDFLIB_TOO_MANY_SIGNALS -21 #define EDFLIB_NO_SAMPLES_IN_RECORD -22 #define EDFLIB_DIGMIN_IS_DIGMAX -23 #define EDFLIB_DIGMAX_LOWER_THAN_DIGMIN -24 #define EDFLIB_PHYSMIN_IS_PHYSMAX -25 #ifdef __cplusplus extern "C" { #endif /* For more info about the EDF and EDF+ format, visit: http://edfplus.info/specs/ */ /* For more info about the BDF and BDF+ format, visit: http://www.teuniz.net/edfbrowser/bdfplus%20format%20description.html */ struct edf_param_struct{ /* this structure contains all the relevant EDF-signal parameters of one signal */ char label[17]; /* label (name) of the signal, null-terminated string */ long long smp_in_file; /* number of samples of this signal in the file */ double phys_max; /* physical maximum, usually the maximum input of the ADC */ double phys_min; /* physical minimum, usually the minimum input of the ADC */ int dig_max; /* digital maximum, usually the maximum output of the ADC, can not not be higher than 32767 for EDF or 8388607 for BDF */ int dig_min; /* digital minimum, usually the minimum output of the ADC, can not not be lower than -32768 for EDF or -8388608 for BDF */ int smp_in_datarecord; /* number of samples of this signal in a datarecord */ char physdimension[9]; /* physical dimension (uV, bpm, mA, etc.), null-terminated string */ char prefilter[81]; /* null-terminated string */ char transducer[81]; /* null-terminated string */ }; struct edf_annotation_struct{ /* this structure is used for annotations */ long long onset; /* onset time of the event, expressed in units of 100 nanoSeconds and relative to the starttime in the header */ char duration[16]; /* duration time, this is a null-terminated ASCII text-string */ char annotation[EDFLIB_MAX_ANNOTATION_LEN + 1]; /* description of the event in UTF-8, this is a null terminated string */ }; struct edf_hdr_struct{ /* this structure contains all the relevant EDF header info and will be filled when calling the function edf_open_file_readonly() */ int handle; /* a handle (identifier) used to distinguish the different files */ int filetype; /* 0: EDF, 1: EDFplus, 2: BDF, 3: BDFplus, a negative number means an error */ int edfsignals; /* number of EDF signals in the file, annotation channels are NOT included */ long long file_duration; /* duration of the file expressed in units of 100 nanoSeconds */ int startdate_day; int startdate_month; int startdate_year; long long starttime_subsecond; /* starttime offset expressed in units of 100 nanoSeconds. Is always less than 10000000 (one second). Only used by EDFplus and BDFplus */ int starttime_second; int starttime_minute; int starttime_hour; char patient[81]; /* null-terminated string, contains patientfield of header, is always empty when filetype is EDFPLUS or BDFPLUS */ char recording[81]; /* null-terminated string, contains recordingfield of header, is always empty when filetype is EDFPLUS or BDFPLUS */ char patientcode[81]; /* null-terminated string, is always empty when filetype is EDF or BDF */ char gender[16]; /* null-terminated string, is always empty when filetype is EDF or BDF */ char birthdate[16]; /* null-terminated string, is always empty when filetype is EDF or BDF */ char patient_name[81]; /* null-terminated string, is always empty when filetype is EDF or BDF */ char patient_additional[81]; /* null-terminated string, is always empty when filetype is EDF or BDF */ char admincode[81]; /* null-terminated string, is always empty when filetype is EDF or BDF */ char technician[81]; /* null-terminated string, is always empty when filetype is EDF or BDF */ char equipment[81]; /* null-terminated string, is always empty when filetype is EDF or BDF */ char recording_additional[81]; /* null-terminated string, is always empty when filetype is EDF or BDF */ long long datarecord_duration; /* duration of a datarecord expressed in units of 100 nanoSeconds */ long long datarecords_in_file; /* number of datarecords in the file */ long long annotations_in_file; /* number of annotations in the file */ struct edf_param_struct signalparam[EDFLIB_MAXSIGNALS]; /* array of structs which contain the relevant signal parameters */ }; /***************** the following functions are used to read files **************************/ int edfopen_file_readonly(const char *path, struct edf_hdr_struct *edfhdr, int read_annotations); /* opens an existing file for reading */ /* path is a null-terminated string containing the path to the file */ /* hdr is a pointer to an edf_hdr_struct, all fields in this struct will be overwritten */ /* the edf_hdr_struct will be filled with all the relevant header- and signalinfo/parameters */ /* read_annotations must have one of the following values: */ /* EDFLIB_DO_NOT_READ_ANNOTATIONS annotations will not be read (this saves time when opening a very large EDFplus or BDFplus file */ /* EDFLIB_READ_ANNOTATIONS annotations will be read immediately, stops when an annotation has */ /* been found which contains the description "Recording ends" */ /* EDFLIB_READ_ALL_ANNOTATIONS all annotations will be read immediately */ /* returns 0 on success, in case of an error it returns -1 and an errorcode will be set in the member "filetype" of struct edf_hdr_struct */ /* This function is required if you want to read a file */ int edfread_physical_samples(int handle, int edfsignal, int n, double *buf); /* reads n samples from edfsignal, starting from the current sample position indicator, into buf (edfsignal starts at 0) */ /* the values are converted to their physical values e.g. microVolts, beats per minute, etc. */ /* bufsize should be equal to or bigger than sizeof(double[n]) */ /* the sample position indicator will be increased with the amount of samples read */ /* returns the amount of samples read (this can be less than n or zero!) */ /* or -1 in case of an error */ int edfread_digital_samples(int handle, int edfsignal, int n, int *buf); /* reads n samples from edfsignal, starting from the current sample position indicator, into buf (edfsignal starts at 0) */ /* the values are the "raw" digital values */ /* bufsize should be equal to or bigger than sizeof(int[n]) */ /* the sample position indicator will be increased with the amount of samples read */ /* returns the amount of samples read (this can be less than n or zero!) */ /* or -1 in case of an error */ long long edfseek(int handle, int edfsignal, long long offset, int whence); /* The edfseek() function sets the sample position indicator for the edfsignal pointed to by edfsignal. */ /* The new position, measured in samples, is obtained by adding offset samples to the position specified by whence. */ /* If whence is set to EDFSEEK_SET, EDFSEEK_CUR, or EDFSEEK_END, the offset is relative to the start of the file, */ /* the current position indicator, or end-of-file, respectively. */ /* Returns the current offset. Otherwise, -1 is returned. */ /* note that every signal has it's own independent sample position indicator and edfseek() affects only one of them */ long long edftell(int handle, int edfsignal); /* The edftell() function obtains the current value of the sample position indicator for the edfsignal pointed to by edfsignal. */ /* Returns the current offset. Otherwise, -1 is returned */ /* note that every signal has it's own independent sample position indicator and edftell() affects only one of them */ void edfrewind(int handle, int edfsignal); /* The edfrewind() function sets the sample position indicator for the edfsignal pointed to by edfsignal to the beginning of the file. */ /* It is equivalent to: (void) edfseek(int handle, int edfsignal, 0LL, EDFSEEK_SET) */ /* note that every signal has it's own independent sample position indicator and edfrewind() affects only one of them */ int edf_get_annotation(int handle, int n, struct edf_annotation_struct *annot); /* Fills the edf_annotation_struct with the annotation n, returns 0 on success, otherwise -1 */ /* The string that describes the annotation/event is encoded in UTF-8 */ /* To obtain the number of annotations in a file, check edf_hdr_struct -> annotations_in_file. */ /* Notes: Annotationsignals EDFplus and BDFplus store the annotations in one or more signals (in order to be backwards compatibel with EDF and BDF). The counting of the signals in the file starts at 0. Signals used for annotations are skipped by EDFlib. This means that the annotationsignal(s) in the file are hided. Use the function edf_get_annotation() to get the annotations. So, when a file contains 5 signals and the third signal is used to store the annotations, the library will report that there are only 4 signals in the file. The library will "map" the signalnumbers as follows: 0->0, 1->1, 2->3, 3->4. This way you don't need to worry about which signals are annotationsignals. The library will do it for you. How the library stores time-values To avoid rounding errors, the library stores some timevalues in variables of type long long int. In order not to loose the subsecond precision, all timevalues have been multiplied by 10000000. This will limit the timeresolution to 100 nanoSeconds. To calculate the amount of seconds, divide the timevalue by 10000000 or use the macro EDFLIB_TIME_DIMENSION which is declared in edflib.h. The following variables do use this when you open a file in read mode: "file_duration", "starttime_subsecond" and "onset". */ /***************** the following functions are used to read or write files **************************/ int edfclose_file(int handle); /* closes (and in case of writing, finalizes) the file */ /* returns -1 in case of an error, 0 on success */ /* this function MUST be called when you are finished reading or writing */ /* This function is required after reading or writing. Failing to do so will cause */ /* unnessecary memory usage and in case of writing it will cause a corrupted and incomplete file */ int edflib_version(void); /* Returns the version number of this library, multiplied by hundred. if version is "1.00" than it will return 100 */ int edflib_is_file_used(const char *path); /* returns 1 if the file is used, either for reading or writing */ /* otherwise returns 0 */ int edflib_get_number_of_open_files(void); /* returns the number of open files, either for reading or writing */ int edflib_get_handle(int file_number); /* returns the handle of an opened file, either for reading or writing */ /* file_number starts with 0 */ /* returns -1 if the file is not opened */ /***************** the following functions are used to write files **************************/ int edfopen_file_writeonly(const char *path, int filetype, int number_of_signals); /* opens an new file for writing. warning, an already existing file with the same name will be silently overwritten without advance warning!! */ /* path is a null-terminated string containing the path and name of the file */ /* filetype must be EDFLIB_FILETYPE_EDFPLUS or EDFLIB_FILETYPE_BDFPLUS */ /* returns a handle on success, you need this handle for the other functions */ /* in case of an error it returns a negative number corresponding to one of the following values: */ /* EDFLIB_MALLOC_ERROR */ /* EDFLIB_NO_SUCH_FILE_OR_DIRECTORY */ /* EDFLIB_MAXFILES_REACHED */ /* EDFLIB_FILE_ALREADY_OPENED */ /* EDFLIB_NUMBER_OF_SIGNALS_INVALID */ /* This function is required if you want to write a file */ int edf_set_samplefrequency(int handle, int edfsignal, int samplefrequency); /* Sets the samplefrequency of signal edfsignal. */ /* Returns 0 on success, otherwise -1 */ /* This function is required for every signal and can be called only after opening a */ /* file in writemode and before the first sample write action */ int edf_set_physical_maximum(int handle, int edfsignal, double phys_max); /* Sets the maximum physical value of signal edfsignal. (the value of the input of the ADC when the output equals the value of "digital maximum") */ /* Returns 0 on success, otherwise -1 */ /* This function is required for every signal and can be called only after opening a */ /* file in writemode and before the first sample write action */ int edf_set_physical_minimum(int handle, int edfsignal, double phys_min); /* Sets the minimum physical value of signal edfsignal. (the value of the input of the ADC when the output equals the value of "digital minimum") */ /* Usually this will be (-(phys_max)) */ /* Returns 0 on success, otherwise -1 */ /* This function is required for every signal and can be called only after opening a */ /* file in writemode and before the first sample write action */ int edf_set_digital_maximum(int handle, int edfsignal, int dig_max); /* Sets the maximum digital value of signal edfsignal. The maximum value is 32767 for EDF+ and 8388607 for BDF+ */ /* Usually it's the extreme output of the ADC */ /* Returns 0 on success, otherwise -1 */ /* This function is required for every signal and can be called only after opening a file in writemode */ /* and before the first sample write action */ int edf_set_digital_minimum(int handle, int edfsignal, int dig_min); /* Sets the minimum digital value of signal edfsignal. The minimum value is -32768 for EDF+ and -8388608 for BDF+ */ /* Usually it's the extreme output of the ADC */ /* Usually this will be (-(dig_max + 1)) */ /* Returns 0 on success, otherwise -1 */ /* This function is required for every signal and can be called only after opening a file in writemode */ /* and before the first sample write action */ int edf_set_label(int handle, int edfsignal, const char *label); /* Sets the label (name) of signal edfsignal. ("FP1", "SaO2", etc.) */ /* label is a pointer to a NULL-terminated ASCII-string containing the label (name) of the signal edfsignal */ /* Returns 0 on success, otherwise -1 */ /* This function is recommanded for every signal when you want to write a file */ /* and can be called only after opening a file in writemode and before the first sample write action */ int edf_set_prefilter(int handle, int edfsignal, const char *prefilter); /* Sets the prefilter of signal edfsignal ("HP:0.1Hz", "LP:75Hz N:50Hz", etc.). */ /* prefilter is a pointer to a NULL-terminated ASCII-string containing the prefilter text of the signal edfsignal */ /* Returns 0 on success, otherwise -1 */ /* This function is optional and can be called only after opening a file in writemode and before */ /* the first sample write action */ int edf_set_transducer(int handle, int edfsignal, const char *transducer); /* Sets the transducer of signal edfsignal ("AgAgCl cup electrodes", etc.). */ /* transducer is a pointer to a NULL-terminated ASCII-string containing the transducer text of the signal edfsignal */ /* Returns 0 on success, otherwise -1 */ /* This function is optional and can be called only after opening a file in writemode and before */ /* the first sample write action */ int edf_set_physical_dimension(int handle, int edfsignal, const char *phys_dim); /* Sets the physical dimension of signal edfsignal. ("uV", "BPM", "mA", "Degr.", etc.) */ /* phys_dim is a pointer to a NULL-terminated ASCII-string containing the physical dimension of the signal edfsignal */ /* Returns 0 on success, otherwise -1 */ /* This function is recommanded for every signal when you want to write a file */ /* and can be called only after opening a file in writemode and before the first sample write action */ int edf_set_startdatetime(int handle, int startdate_year, int startdate_month, int startdate_day, int starttime_hour, int starttime_minute, int starttime_second); /* Sets the startdate and starttime. */ /* year: 1970 - 3000, month: 1 - 12, day: 1 - 31 */ /* hour: 0 - 23, minute: 0 - 59, second: 0 - 59 */ /* If not called, the library will use the system date and time at runtime */ /* Returns 0 on success, otherwise -1 */ /* This function is optional and can be called only after opening a file in writemode */ /* and before the first sample write action */ int edf_set_patientname(int handle, const char *patientname); /* Sets the patientname. patientname is a pointer to a null-terminated ASCII-string. */ /* Returns 0 on success, otherwise -1 */ /* This function is optional and can be called only after opening a file in writemode */ /* and before the first sample write action */ int edf_set_patientcode(int handle, const char *patientcode); /* Sets the patientcode. patientcode is a pointer to a null-terminated ASCII-string. */ /* Returns 0 on success, otherwise -1 */ /* This function is optional and can be called only after opening a file in writemode */ /* and before the first sample write action */ int edf_set_gender(int handle, int gender); /* Sets the gender. 1 is male, 0 is female. */ /* Returns 0 on success, otherwise -1 */ /* This function is optional and can be called only after opening a file in writemode */ /* and before the first sample write action */ int edf_set_birthdate(int handle, int birthdate_year, int birthdate_month, int birthdate_day); /* Sets the birthdate. */ /* year: 1800 - 3000, month: 1 - 12, day: 1 - 31 */ /* This function is optional */ /* Returns 0 on success, otherwise -1 */ /* This function is optional and can be called only after opening a file in writemode */ /* and before the first sample write action */ int edf_set_patient_additional(int handle, const char *patient_additional); /* Sets the additional patientinfo. patient_additional is a pointer to a null-terminated ASCII-string. */ /* Returns 0 on success, otherwise -1 */ /* This function is optional and can be called only after opening a file in writemode */ /* and before the first sample write action */ int edf_set_admincode(int handle, const char *admincode); /* Sets the admincode. admincode is a pointer to a null-terminated ASCII-string. */ /* Returns 0 on success, otherwise -1 */ /* This function is optional and can be called only after opening a file in writemode */ /* and before the first sample write action */ int edf_set_technician(int handle, const char *technician); /* Sets the technicians name. technician is a pointer to a null-terminated ASCII-string. */ /* Returns 0 on success, otherwise -1 */ /* This function is optional and can be called only after opening a file in writemode */ /* and before the first sample write action */ int edf_set_equipment(int handle, const char *equipment); /* Sets the name of the equipment used during the aquisition. equipment is a pointer to a null-terminated ASCII-string. */ /* Returns 0 on success, otherwise -1 */ /* This function is optional and can be called only after opening a file in writemode */ /* and before the first sample write action */ int edf_set_recording_additional(int handle, const char *recording_additional); /* Sets the additional recordinginfo. recording_additional is a pointer to a null-terminated ASCII-string. */ /* Returns 0 on success, otherwise -1 */ /* This function is optional and can be called only after opening a file in writemode */ /* and before the first sample write action */ int edfwrite_physical_samples(int handle, double *buf); /* Writes n physical samples (uV, mA, Ohm) from *buf belonging to one signal */ /* where n is the samplefrequency of that signal. */ /* The physical samples will be converted to digital samples using the */ /* values of physical maximum, physical minimum, digital maximum and digital minimum */ /* The number of samples written is equal to the samplefrequency of the signal */ /* Size of buf should be equal to or bigger than sizeof(double[samplefrequency]) */ /* Call this function for every signal in the file. The order is important! */ /* When there are 4 signals in the file, the order of calling this function */ /* must be: signal 0, signal 1, signal 2, signal 3, signal 0, signal 1, signal 2, etc. */ /* Returns 0 on success, otherwise -1 */ int edf_blockwrite_physical_samples(int handle, double *buf); /* Writes physical samples (uV, mA, Ohm) from *buf */ /* buf must be filled with samples from all signals, starting with n samples of signal 0, n samples of signal 1, n samples of signal 2, etc. */ /* where n is the samplefrequency of that signal. */ /* buf must be filled with samples from all signals, starting with signal 0, 1, 2, etc. */ /* one block equals one second */ /* The physical samples will be converted to digital samples using the */ /* values of physical maximum, physical minimum, digital maximum and digital minimum */ /* The number of samples written is equal to the sum of the samplefrequencies of all signals */ /* Size of buf should be equal to or bigger than sizeof(double) multiplied by the sum of the samplefrequencies of all signals */ /* Returns 0 on success, otherwise -1 */ int edfwrite_digital_short_samples(int handle, short *buf); /* Writes n "raw" digital samples from *buf belonging to one signal */ /* where n is the samplefrequency of that signal. */ /* The samples will be written to the file without any conversion. */ /* Because the size of a short is 16-bit, do not use this function with BDF (24-bit) */ /* The number of samples written is equal to the samplefrequency of the signal */ /* Size of buf should be equal to or bigger than sizeof(short[samplefrequency]) */ /* Call this function for every signal in the file. The order is important! */ /* When there are 4 signals in the file, the order of calling this function */ /* must be: signal 0, signal 1, signal 2, signal 3, signal 0, signal 1, signal 2, etc. */ /* Returns 0 on success, otherwise -1 */ int edfwrite_digital_samples(int handle, int *buf); /* Writes n "raw" digital samples from *buf belonging to one signal */ /* where n is the samplefrequency of that signal. */ /* The 16 (or 24 in case of BDF) least significant bits of the sample will be written to the */ /* file without any conversion. */ /* The number of samples written is equal to the samplefrequency of the signal */ /* Size of buf should be equal to or bigger than sizeof(int[samplefrequency]) */ /* Call this function for every signal in the file. The order is important! */ /* When there are 4 signals in the file, the order of calling this function */ /* must be: signal 0, signal 1, signal 2, signal 3, signal 0, signal 1, signal 2, etc. */ /* Returns 0 on success, otherwise -1 */ int edf_blockwrite_digital_3byte_samples(int handle, void *buf); /* Writes "raw" digital samples from *buf. */ /* buf must be filled with samples from all signals, starting with n samples of signal 0, n samples of signal 1, n samples of signal 2, etc. */ /* where n is the samplefrequency of that signal. */ /* One block equals one second. One sample equals 3 bytes, order is little endian (least significant byte first) */ /* Encoding is second's complement, most significant bit of most significant byte is the sign-bit */ /* The samples will be written to the file without any conversion. */ /* Because the size of a 3-byte sample is 24-bit, this function can only be used when writing a BDF file */ /* The number of samples written is equal to the sum of the samplefrequencies of all signals. */ /* Size of buf should be equal to or bigger than: the sum of the samplefrequencies of all signals x 3 bytes */ /* Returns 0 on success, otherwise -1 */ int edf_blockwrite_digital_short_samples(int handle, short *buf); /* Writes "raw" digital samples from *buf. */ /* buf must be filled with samples from all signals, starting with n samples of signal 0, n samples of signal 1, n samples of signal 2, etc. */ /* where n is the samplefrequency of that signal. */ /* One block equals one second. */ /* The samples will be written to the file without any conversion. */ /* Because the size of a short is 16-bit, do not use this function with BDF (24-bit) */ /* The number of samples written is equal to the sum of the samplefrequencies of all signals. */ /* Size of buf should be equal to or bigger than sizeof(short) multiplied by the sum of the samplefrequencies of all signals */ /* Returns 0 on success, otherwise -1 */ int edf_blockwrite_digital_samples(int handle, int *buf); /* Writes "raw" digital samples from *buf. */ /* buf must be filled with samples from all signals, starting with n samples of signal 0, n samples of signal 1, n samples of signal 2, etc. */ /* where n is the samplefrequency of that signal. */ /* One block equals one second. */ /* The 16 (or 24 in case of BDF) least significant bits of the sample will be written to the */ /* file without any conversion. */ /* The number of samples written is equal to the sum of the samplefrequencies of all signals. */ /* Size of buf should be equal to or bigger than sizeof(int) multiplied by the sum of the samplefrequencies of all signals */ /* Returns 0 on success, otherwise -1 */ int edfwrite_annotation_utf8(int handle, long long onset, long long duration, const char *description); /* writes an annotation/event to the file */ /* onset is relative to the starttime and startdate of the file */ /* onset and duration are in units of 100 microSeconds! resolution is 0.0001 second! */ /* for example: 34.071 seconds must be written as 340710 */ /* if duration is unknown or not applicable: set a negative number (-1) */ /* description is a null-terminated UTF8-string containing the text that describes the event */ /* This function is optional and can be called only after opening a file in writemode */ /* and before closing the file */ int edfwrite_annotation_latin1(int handle, long long onset, long long duration, const char *description); /* writes an annotation/event to the file */ /* onset is relative to the starttime and startdate of the file */ /* onset and duration are in units of 100 microSeconds! resolution is 0.0001 second! */ /* for example: 34.071 seconds must be written as 340710 */ /* if duration is unknown or not applicable: set a negative number (-1) */ /* description is a null-terminated Latin1-string containing the text that describes the event */ /* This function is optional and can be called only after opening a file in writemode */ /* and before closing the file */ int edf_set_datarecord_duration(int handle, int duration); /* Sets the datarecord duration. The default value is 1 second. */ /* ATTENTION: the argument "duration" is expressed in units of 10 microSeconds! */ /* So, if you want to set the datarecord duration to 0.1 second, you must give */ /* the argument "duration" a value of "10000". */ /* This function is optional, normally you don't need to change the default value. */ /* The datarecord duration must be in the range 0.001 to 60 seconds. */ /* Returns 0 on success, otherwise -1 */ /* This function is NOT REQUIRED but can be called after opening a */ /* file in writemode and before the first sample write action. */ /* This function can be used when you want to use a samplerate */ /* which is not an integer. For example, if you want to use a samplerate of 0.5 Hz, */ /* set the samplefrequency to 5 Hz and the datarecord duration to 10 seconds, */ /* or set the samplefrequency to 1 Hz and the datarecord duration to 2 seconds. */ /* Do not use this function, except when absolutely necessary! */ int edf_set_number_of_annotation_signals(int handle, int annot_signals); /* Sets the number of annotation signals. The default value is 1 */ /* This function is optional and can be called only after opening a file in writemode */ /* and before the first sample write action */ /* Normally you don't need to change the default value. Only when the number of annotations */ /* you want to write is more than the number of seconds of the duration of the recording, you can use */ /* this function to increase the storage space for annotations */ /* Minimum is 1, maximum is 64 */ #ifdef __cplusplus } /* extern "C" */ #endif #endif edfbrowser_153_source/PaxHeaders.2978/ascii2edf.h0000644000175000001440000000012712251654530020155 xustar000000000000000029 mtime=1386699096.46603258 29 atime=1386699096.46603258 29 ctime=1386699096.46603258 edfbrowser_153_source/ascii2edf.h0000644000175000001440000000657712251654530017721 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef UI_ASCII2EDFFORM_H #define UI_ASCII2EDFFORM_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "popup_messagewindow.h" #include "xml.h" #include "utils.h" #define ASCII_MAX_EDF_SIGNALS 512 #define ASCII_MAX_LINE_LEN 2048 class UI_ASCII2EDFapp : public QObject { Q_OBJECT public: UI_ASCII2EDFapp(char *recent_dir=NULL, char *save_dir=NULL); private: QDialog *ascii2edfDialog; QLabel *SeparatorLabel, *NumsignalsLabel, *DatastartLabel, *SamplefreqLabel, *PatientnameLabel, *RecordingLabel, *DatetimeLabel, *SignalsLabel, *autoPhysicalMaximumLabel; QRadioButton *edfButton, *bdfButton; QGroupBox *groupbox1; QVBoxLayout *vbox1; QLineEdit *SeparatorLineEdit, *PatientnameLineEdit, *RecordingLineEdit; QSpinBox *NumcolumnsSpinbox, *DatastartSpinbox; QDoubleSpinBox *SamplefreqSpinbox; QDateTimeEdit *StartDatetimeedit; QCheckBox *autoPhysicalMaximumCheckbox; QTableWidget *SignalsTablewidget; QPushButton *GoButton, *CloseButton, *SaveButton, *LoadButton; char separator, *recent_opendir, *recent_savedir; int edfsignals, startline, columns, column_enabled[ASCII_MAX_EDF_SIGNALS], autoPhysicalMaximum, edf_format; double samplefrequency, datrecduration, sensitivity[ASCII_MAX_EDF_SIGNALS], value[ASCII_MAX_EDF_SIGNALS], physmax[ASCII_MAX_EDF_SIGNALS]; int check_input(void); private slots: void numofcolumnschanged(int); void gobuttonpressed(); void savebuttonpressed(); void loadbuttonpressed(); void autoPhysicalMaximumCheckboxChanged(int); }; #endif edfbrowser_153_source/PaxHeaders.2978/about_dialog.h0000644000175000001440000000012712251654530020755 xustar000000000000000029 mtime=1386699096.46603258 29 atime=1386699096.46603258 29 ctime=1386699096.46603258 edfbrowser_153_source/about_dialog.h0000644000175000001440000000327512251654530020511 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef ABOUT_FORM1_H #define ABOUT_FORM1_H #include #include #include #include #include #include #include #include #include "global.h" #include "mainwindow.h" class UI_Aboutwindow : public QObject { Q_OBJECT public: UI_Aboutwindow(UI_Mainwindow *); private: QDialog *AboutDialog; QPushButton *pushButton1; QTextEdit *textedit1; QHBoxLayout *hlayout1; QVBoxLayout *vlayout1; }; #endif // ABOUT_FORM1_H edfbrowser_153_source/PaxHeaders.2978/adjustfiltersettings.h0000644000175000001440000000012712251654530022605 xustar000000000000000029 mtime=1386699096.46603258 29 atime=1386699096.46603258 29 ctime=1386699096.46603258 edfbrowser_153_source/adjustfiltersettings.h0000644000175000001440000000466512251654530022345 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * The current version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef ADJUSTFILTERSETTINGS_H #define ADJUSTFILTERSETTINGS_H #include #include #include #include #include #include #include #include #include "global.h" #include "mainwindow.h" #include "viewcurve.h" #include "popup_messagewindow.h" #include "ravg_filter.h" #include "third_party/fidlib/fidlib.h" class UI_Mainwindow; class ViewCurve; class AdjustFilterSettings : public QObject { Q_OBJECT public: AdjustFilterSettings(struct signalcompblock *, QWidget *); private: int filter_nr, filter_cnt, type, model, order, size, brand[MAXFILTERS]; double frequency1, frequency2, ripple; struct signalcompblock * signalcomp; UI_Mainwindow *mainwindow; ViewCurve *maincurve; QDialog *filtersettings_dialog; QLabel *label[5]; QComboBox *filterbox, *stepsizebox; QSpinBox *orderbox; QDoubleSpinBox *freq1box, *freq2box; QPushButton *CloseButton; void update_filter(void); private slots: void freqbox1valuechanged(double); void freqbox2valuechanged(double); void orderboxvaluechanged(int); void stepsizeboxchanged(int); void filterboxchanged(int); }; #endif // ADJUSTFILTERSETTINGS_H edfbrowser_153_source/PaxHeaders.2978/save_annots.h0000644000175000001440000000013212251654530020640 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/save_annots.h0000644000175000001440000000301612251654530020371 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef SAVE_ANNOTATIONS_H #define SAVE_ANNOTATIONS_H #include #include #include #include #include #include "global.h" #include "mainwindow.h" #include "utils.h" #include "edf_annot_list.h" int save_annotations(UI_Mainwindow *, FILE *, struct edfhdrblock *, struct annotationblock *); #endif edfbrowser_153_source/PaxHeaders.2978/averager_curve_wnd.cpp0000644000175000001440000000013212251654530022523 xustar000000000000000030 mtime=1386699096.477032522 30 atime=1386699096.476032527 30 ctime=1386699096.477032522 edfbrowser_153_source/averager_curve_wnd.cpp0000644000175000001440000004165412251654530022266 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "averager_curve_wnd.h" UI_AverageCurveWindow::UI_AverageCurveWindow(struct signalcompblock *signal_comp, QWidget *w_parent, int number, double *abuf, double maxvalue, double minvalue, long long apagetime, long long samples_on_screen, int acnt, int trigger_position, char *annotation, double avg__period) { char str[1024]; averager_curve_dialog_is_destroyed = 0; mainwindow = (UI_Mainwindow *)w_parent; signalcomp = signal_comp; averagecurvedialognumber = number; pagetime = apagetime; pagetime /= TIME_DIMENSION; avgbuf = abuf; avg_max_value = maxvalue; avg_min_value = minvalue; avg_samples_on_screen = samples_on_screen; avg_cnt = acnt; avg_trigger_position_ratio = trigger_position; avg_period = avg__period; strcpy(avg_annotation, annotation); flywheel_value = 1000; averager_curve_dialog = new QDialog; averager_curve_dialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); averager_curve_dialog->setMinimumSize(QSize(650, 480)); averager_curve_dialog->setSizeGripEnabled(TRUE); averager_curve_dialog->setModal(FALSE); averager_curve_dialog->setWindowFlags(Qt::Window | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint); averager_curve_dialog->setWindowIcon(QIcon(":/images/edf.png")); strcpy(str, "Averaging "); strcat(str, signalcomp->signallabel); averager_curve_dialog->setWindowTitle(str); curve1 = new SignalCurve; curve1->setSignalColor(Qt::green); curve1->setBackgroundColor(Qt::black); curve1->setRasterColor(Qt::gray); curve1->setCrosshairColor(Qt::red); curve1->setTraceWidth(0); curve1->setH_label("sec"); curve1->setLowerLabel("Time"); curve1->setV_label(signalcomp->physdimension); curve1->setDashBoardEnabled(FALSE); curve1->setMarker1Color(Qt::yellow); curve1->create_button("to EDF/BDF"); sprintf(str, "Averaging %i triggers \"%s\"", avg_cnt, avg_annotation); curve1->setUpperLabel1(str); flywheel1 = new UI_Flywheel; flywheel1->setMinimumSize(20, 85); amplitudeSlider = new QSlider; amplitudeSlider->setOrientation(Qt::Vertical); amplitudeSlider->setMinimum(1); amplitudeSlider->setMaximum(2000); amplitudeSlider->setValue(1100); amplitudeSlider->setInvertedAppearance(TRUE); amplitudeSlider->setMinimumSize(15, 280); amplitudeLabel = new QLabel; amplitudeLabel->setText("Amplitude"); amplitudeLabel->setMinimumSize(100, 15); amplitudeLabel->setAlignment(Qt::AlignHCenter); inversionCheckBox = new QCheckBox("Invert"); inversionCheckBox->setMinimumSize(70, 25); inversionCheckBox->setTristate(FALSE); if(mainwindow->average_upsidedown == 1) { inversionCheckBox->setCheckState(Qt::Checked); } else { inversionCheckBox->setCheckState(Qt::Unchecked); } BWCheckBox = new QCheckBox("B/W"); BWCheckBox->setMinimumSize(70, 25); BWCheckBox->setTristate(FALSE); if(mainwindow->average_bw == 1) { BWCheckBox->setCheckState(Qt::Checked); } else { BWCheckBox->setCheckState(Qt::Unchecked); } vlayout3 = new QVBoxLayout; vlayout3->addStretch(100); vlayout3->addWidget(flywheel1, 100); vlayout3->addStretch(100); hlayout4 = new QHBoxLayout; hlayout4->addStretch(100); hlayout4->addLayout(vlayout3, 100); hlayout4->addStretch(100); hlayout4->addWidget(amplitudeSlider, 300); vlayout2 = new QVBoxLayout; vlayout2->setSpacing(20); vlayout2->addStretch(100); vlayout2->addWidget(amplitudeLabel, 0, Qt::AlignHCenter); vlayout2->addLayout(hlayout4, 200); vlayout2->addWidget(inversionCheckBox); vlayout2->addWidget(BWCheckBox); spanSlider = new QSlider; spanSlider->setOrientation(Qt::Horizontal); spanSlider->setMinimum(10); spanSlider->setMaximum(1000); spanSlider->setValue(1000); spanSlider->setMinimumSize(500, 15); spanLabel = new QLabel; spanLabel->setText("Span"); spanLabel->setMinimumSize(110, 15); spanLabel->setAlignment(Qt::AlignHCenter); centerSlider = new QSlider; centerSlider->setOrientation(Qt::Horizontal); centerSlider->setMinimum(0); centerSlider->setMaximum(1000); centerSlider->setValue(250); centerSlider->setMinimumSize(500, 15); centerLabel = new QLabel; centerLabel->setText("Center"); centerLabel->setMinimumSize(110, 15); centerLabel->setAlignment(Qt::AlignHCenter); hlayout1 = new QHBoxLayout; hlayout1->setSpacing(20); hlayout1->addLayout(vlayout2); hlayout1->addWidget(curve1, 100); hlayout2 = new QHBoxLayout; hlayout2->setSpacing(20); hlayout2->addWidget(spanLabel); hlayout2->addWidget(spanSlider); hlayout2->addStretch(100); hlayout3 = new QHBoxLayout; hlayout3->setSpacing(20); hlayout3->addWidget(centerLabel); hlayout3->addWidget(centerSlider); hlayout3->addStretch(100); vlayout1 = new QVBoxLayout; vlayout1->setSpacing(20); vlayout1->addLayout(hlayout1); vlayout1->addLayout(hlayout2); vlayout1->addLayout(hlayout3); averager_curve_dialog->setLayout(vlayout1); QObject::connect(amplitudeSlider, SIGNAL(valueChanged(int)), this, SLOT(sliderMoved(int))); QObject::connect(inversionCheckBox, SIGNAL(stateChanged(int)), this, SLOT(sliderMoved(int))); QObject::connect(BWCheckBox, SIGNAL(stateChanged(int)), this, SLOT(sliderMoved(int))); QObject::connect(spanSlider, SIGNAL(valueChanged(int)), this, SLOT(sliderMoved(int))); QObject::connect(centerSlider, SIGNAL(valueChanged(int)), this, SLOT(sliderMoved(int))); QObject::connect(averager_curve_dialog, SIGNAL(destroyed(QObject *)), this, SLOT(averager_curve_dialogDestroyed(QObject *))); QObject::connect(curve1, SIGNAL(extra_button_clicked()), this, SLOT(export_edf())); QObject::connect(flywheel1, SIGNAL(dialMoved(int)), this, SLOT(update_flywheel(int))); sliderMoved(0); averager_curve_dialog->show(); } 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; jfidfilter_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; jravg_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; ivalue() * steps / 1000; startstep = centerSlider->value() * (steps - spanstep) / 1000; stopstep = startstep + spanstep; avg_mid_value = (avg_max_value + avg_min_value) / 2.0; avg_peak_value = (avg_max_value - avg_min_value) / 2.0; avg_peak_value = (avg_peak_value * (double)amplitudeSlider->value() / 1000.0) * ((double)flywheel_value / 1000.0); dtmp1 = avg_mid_value + avg_peak_value; dtmp2 = avg_mid_value - avg_peak_value; if(inversionCheckBox->isChecked() == TRUE) { curve1->setUpsidedownEnabled(TRUE); mainwindow->average_upsidedown = 1; } else { curve1->setUpsidedownEnabled(FALSE); mainwindow->average_upsidedown = 0; } if(BWCheckBox->isChecked() == TRUE) { curve1->setSignalColor(Qt::black); curve1->setBackgroundColor(Qt::white); curve1->setRasterColor(Qt::black); curve1->setMarker1Color(Qt::black); curve1->setBorderColor(Qt::white); curve1->setTextColor(Qt::black); curve1->setCrosshairColor(Qt::black); mainwindow->average_bw = 1; } else { curve1->setSignalColor(Qt::green); curve1->setBackgroundColor(Qt::black); curve1->setRasterColor(Qt::gray); curve1->setMarker1Color(Qt::yellow); curve1->setBorderColor(Qt::lightGray); curve1->setTextColor(Qt::black); curve1->setCrosshairColor(Qt::red); mainwindow->average_bw = 0; } curve1->drawCurve(avgbuf + startstep, stopstep - startstep, dtmp1, dtmp2); max_sec = pagetime * stopstep / steps - (pagetime * (1.0 / avg_trigger_position_ratio)); precision = 0; if(max_sec < 100.0) { precision = 1; } if(max_sec < 10.0) { precision = 2; } if(max_sec < 1.0) { precision = 3; } if(max_sec < 0.1) { precision = 4; } start_sec = pagetime * startstep / steps - (pagetime * (1.0 / avg_trigger_position_ratio)); curve1->setH_RulerValues(start_sec, max_sec); centerLabel->setText(QString::number(start_sec + ((max_sec - start_sec) / 2.0), 'f', precision).append(" sec").prepend("Center ")); spanLabel->setText(QString::number(max_sec - start_sec, 'f', precision).append(" sec").prepend("Span ")); if(avg_trigger_position_ratio > 0) { markerstep = steps / avg_trigger_position_ratio; if((markerstep > startstep) && (markerstep < stopstep)) { curve1->setMarker1Enabled(TRUE); curve1->setMarker1Position((((double)steps / (double)avg_trigger_position_ratio) - (double)startstep) / (double)spanstep); } else { curve1->setMarker1Enabled(FALSE); } } else { curve1->setMarker1Enabled(FALSE); } } void UI_AverageCurveWindow::averager_curve_dialogDestroyed(QObject *) { averager_curve_dialog_is_destroyed = 1; mainwindow->averagecurvedialog[averagecurvedialognumber] = NULL; delete this; } UI_AverageCurveWindow::~UI_AverageCurveWindow() { int i; if(!averager_curve_dialog_is_destroyed) { averager_curve_dialog->close(); } if(avgbuf != NULL) { free(avgbuf); } mainwindow->averagecurvedialog[averagecurvedialognumber] = NULL; for(i=0; iavg_dialog[i] == (averagecurvedialognumber + 1)) { signalcomp->avg_dialog[i] = 0; } } } void UI_AverageCurveWindow::update_flywheel(int new_value) { flywheel_value += new_value; if(flywheel_value < 10) { flywheel_value = 10; } if(flywheel_value > 100000) { flywheel_value = 100000; } sliderMoved(0); } edfbrowser_153_source/PaxHeaders.2978/utc_date_time.h0000644000175000001440000000013212251654530021126 xustar000000000000000030 mtime=1386699096.468032569 30 atime=1386699096.468032569 30 ctime=1386699096.468032569 edfbrowser_153_source/utc_date_time.h0000644000175000001440000000321212251654530020655 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef UTC_DATE_TIME_INCLUDED #define UTC_DATE_TIME_INCLUDED #include #ifdef __cplusplus extern "C" { #endif struct date_time_struct{ int year; int month; int day; int hour; int minute; int second; char month_str[4]; }; void utc_to_date_time(long long, struct date_time_struct *); void date_time_to_utc(long long *, struct date_time_struct); #ifdef __cplusplus } /* extern "C" */ #endif #endif edfbrowser_153_source/PaxHeaders.2978/edfbrowser.pro0000644000175000001440000000013212251654530021033 xustar000000000000000030 mtime=1386699096.484032485 30 atime=1386699096.484032485 30 ctime=1386699096.484032485 edfbrowser_153_source/edfbrowser.pro0000644000175000001440000001156312251654530020572 0ustar00novarausers00000000000000 !contains(QT_MAJOR_VERSION, 4) { error("This program needs Qt version 4") } LIST = 0 1 2 3 4 5 6 for(a, LIST):contains(QT_MINOR_VERSION, $$a):error("you are using an old version of Qt") contains(QT_MINOR_VERSION, 7) { LIST = 0 for(a, LIST):contains(QT_PATCH_VERSION, $$a):error("you are using an old version of Qt") } TEMPLATE = app TARGET = edfbrowser DEPENDPATH += . INCLUDEPATH += . CONFIG += qt CONFIG += warn_on CONFIG += release CONFIG += static CONFIG += largefile QT += network OBJECTS_DIR = ./objects MOC_DIR = ./moc HEADERS += global.h HEADERS += mainwindow.h HEADERS += viewcurve.h HEADERS += popup_messagewindow.h HEADERS += check_edf_file.h HEADERS += show_edf_hdr.h HEADERS += signals_dialog.h HEADERS += signal_chooser.h HEADERS += ascii_export.h HEADERS += edf_compat.h HEADERS += colordialog.h HEADERS += filter.h HEADERS += filter_dialog.h HEADERS += jump_dialog.h HEADERS += about_dialog.h HEADERS += edf_annotations.h HEADERS += annotations_dock.h HEADERS += options_dialog.h HEADERS += nk2edf.h HEADERS += xml.h HEADERS += save_montage_dialog.h HEADERS += load_montage_dialog.h HEADERS += view_montage_dialog.h HEADERS += show_actual_montage_dialog.h HEADERS += print_to_edf.h HEADERS += pagetime_dialog.h HEADERS += print_to_bdf.h HEADERS += ascii2edf.h HEADERS += fino2edf.h HEADERS += nexfin2edf.h HEADERS += edfplusd_cnv.h HEADERS += utc_date_time.h HEADERS += emsa2edf.h HEADERS += special_button.h HEADERS += bdf2edf.h HEADERS += edit_annotation_dock.h HEADERS += popup_save_cancelwindow.h HEADERS += save_annots.h HEADERS += filtercurve.h HEADERS += utils.h HEADERS += fourier.h HEADERS += signalcurve.h HEADERS += spectrumanalyzer.h HEADERS += bi9800.h HEADERS += edflib.h HEADERS += export_annotations.h HEADERS += edit_predefined_mtg.h HEADERS += spectrum_dock.h HEADERS += edf_annot_list.h HEADERS += reduce_signals.h HEADERS += active_file_chooser.h HEADERS += header_editor.h HEADERS += biosemi2bdfplus.h HEADERS += bdf_triggers.h HEADERS += adjustfiltersettings.h HEADERS += import_annotations.h HEADERS += ravg_filter.h HEADERS += wav2edf.h HEADERS += averager_dialog.h HEADERS += averager_curve_wnd.h HEADERS += ecg_filter.h HEADERS += ecg_export.h HEADERS += statistics_dialog.h HEADERS += filteredblockread.h HEADERS += flywheel.h HEADERS += z_score_dialog.h HEADERS += z_ratio_filter.h HEADERS += raw2edf.h HEADERS += check_for_updates.h HEADERS += manscan2edf.h HEADERS += scp_ecg2edf.h HEADERS += unisens2edf.h HEADERS += third_party/fidlib/fidlib.h HEADERS += third_party/fidlib/fidmkf.h HEADERS += third_party/fidlib/fidrf_cmdlist.h HEADERS += third_party/kiss_fft/kiss_fft.h HEADERS += third_party/kiss_fft/_kiss_fft_guts.h HEADERS += third_party/kiss_fft/kiss_fftr.h SOURCES += main.cpp SOURCES += mainwindow.cpp SOURCES += viewcurve.cpp SOURCES += popup_messagewindow.cpp SOURCES += check_edf_file.cpp SOURCES += show_edf_hdr.cpp SOURCES += signals_dialog.cpp SOURCES += signal_chooser.cpp SOURCES += ascii_export.cpp SOURCES += edf_compat.cpp SOURCES += colordialog.cpp SOURCES += filter.cpp SOURCES += filter_dialog.cpp SOURCES += jump_dialog.cpp SOURCES += about_dialog.cpp SOURCES += edf_annotations.cpp SOURCES += annotations_dock.cpp SOURCES += options_dialog.cpp SOURCES += nk2edf.cpp SOURCES += xml.cpp SOURCES += save_montage_dialog.cpp SOURCES += load_montage_dialog.cpp SOURCES += view_montage_dialog.cpp SOURCES += show_actual_montage_dialog.cpp SOURCES += print_to_edf.cpp SOURCES += pagetime_dialog.cpp SOURCES += print_to_bdf.cpp SOURCES += ascii2edf.cpp SOURCES += fino2edf.cpp SOURCES += nexfin2edf.cpp SOURCES += edfplusd_cnv.cpp SOURCES += utc_date_time.c SOURCES += emsa2edf.cpp SOURCES += special_button.cpp SOURCES += bdf2edf.cpp SOURCES += edit_annotation_dock.cpp SOURCES += popup_save_cancelwindow.cpp SOURCES += save_annots.cpp SOURCES += filtercurve.cpp SOURCES += utils.c SOURCES += fourier.c SOURCES += signalcurve.cpp SOURCES += spectrumanalyzer.cpp SOURCES += bi9800.cpp SOURCES += edflib.c SOURCES += export_annotations.cpp SOURCES += edit_predefined_mtg.cpp SOURCES += spectrum_dock.cpp SOURCES += edf_annot_list.c SOURCES += reduce_signals.cpp SOURCES += active_file_chooser.cpp SOURCES += header_editor.cpp SOURCES += biosemi2bdfplus.cpp SOURCES += bdf_triggers.cpp SOURCES += adjustfiltersettings.cpp SOURCES += import_annotations.cpp SOURCES += ravg_filter.cpp SOURCES += wav2edf.cpp SOURCES += averager_dialog.cpp SOURCES += averager_curve_wnd.cpp SOURCES += ecg_filter.cpp SOURCES += ecg_export.cpp SOURCES += statistics_dialog.cpp SOURCES += filteredblockread.cpp SOURCES += flywheel.cpp SOURCES += z_score_dialog.cpp SOURCES += z_ratio_filter.cpp SOURCES += raw2edf.cpp SOURCES += check_for_updates.cpp SOURCES += manscan2edf.cpp SOURCES += scp_ecg2edf.cpp SOURCES += unisens2edf.cpp SOURCES += third_party/fidlib/fidlib.c SOURCES += third_party/kiss_fft/kiss_fft.c SOURCES += third_party/kiss_fft/kiss_fftr.c RESOURCES = images.qrc win32 { RC_FILE = edfbrowser.rc } edfbrowser_153_source/PaxHeaders.2978/biosemi2bdfplus.cpp0000644000175000001440000000013212251654530021744 xustar000000000000000030 mtime=1386699096.477032522 30 atime=1386699096.477032522 30 ctime=1386699096.477032522 edfbrowser_153_source/biosemi2bdfplus.cpp0000644000175000001440000005710612251654530021506 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "biosemi2bdfplus.h" UI_BIOSEMI2BDFPLUSwindow::UI_BIOSEMI2BDFPLUSwindow(QWidget *w_parent) { int i; char str[128]; mainwindow = (UI_Mainwindow *)w_parent; recent_opendir = mainwindow->recent_opendir; recent_savedir = mainwindow->recent_savedir; myobjectDialog = new QDialog; myobjectDialog->setMinimumSize(600, 630); myobjectDialog->setMaximumSize(600, 630); myobjectDialog->setWindowTitle("Biosemi to BDF+ converter"); myobjectDialog->setModal(TRUE); myobjectDialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); label2 = new QLabel(myobjectDialog); label2->setGeometry(20, 20, 200, 26); label2->setText("Trigger Input descriptions:"); label3 = new QLabel(myobjectDialog); label3->setGeometry(290, 350, 200, 26); label3->setText("Annotations will be generated at"); label4 = new QLabel(myobjectDialog); label4->setGeometry(290, 440, 200, 26); label4->setText("of trigger input."); for(i=0; i<16; i++) { label1[i] = new QLabel(myobjectDialog); label1[i]->setGeometry(20, 50 + (i * 30), 20, 26); sprintf(str, "%i", i + 1); label1[i]->setText(str); lineEdit1[i] = new QLineEdit(myobjectDialog); lineEdit1[i]->setGeometry(70, 50 + (i * 30), 120, 26); sprintf(str, "Trigger Input %i", i + 1); lineEdit1[i]->setText(str); lineEdit1[i]->setMaxLength(16); } radioButton1 = new QRadioButton(myobjectDialog); radioButton1->setGeometry(290, 385, 150, 20); radioButton1->setText("rising edge"); radioButton1->setChecked(TRUE); radioButton2 = new QRadioButton(myobjectDialog); radioButton2->setGeometry(290, 415, 150, 20); radioButton2->setText("falling edge"); checkBox1 = new QCheckBox(myobjectDialog); checkBox1->setGeometry(290, 500, 200, 20); checkBox1->setText("measure event duration"); checkBox1->setTristate(FALSE); checkBox1->setChecked(FALSE); selectButton = new QPushButton(myobjectDialog); selectButton->setGeometry(20, 584, 100, 26); selectButton->setText("Select File"); closeButton = new QPushButton(myobjectDialog); closeButton->setGeometry(480, 584, 100, 26); closeButton->setText("Close"); QObject::connect(selectButton, SIGNAL(clicked()), this, SLOT(SelectFileButton())); QObject::connect(closeButton, SIGNAL(clicked()), myobjectDialog, SLOT(close())); inputpath[0] = 0; outputpath[0] = 0; myobjectDialog->exec(); } 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; itext().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= ((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; ionset = (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; iduration[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; iprocessEvents(); if(progress.wasCanceled()) { edfclose_file(hdl_in); edfclose_file(hdl_out); free(buf); return; } } for(i=0; imaincurve->cpu_cnt); if(mainwindow->use_threads == 1) { strcat(str, "\n Multi-Threading is enabled."); } else { strcat(str, "\n Multi-Threading is disabled."); } str[511] = 0; AboutDialog = new QDialog; AboutDialog->setMinimumSize(QSize(640, 480)); AboutDialog->setGeometry(300, 250, 640, 480); AboutDialog->setWindowTitle("About"); AboutDialog->setModal(TRUE); AboutDialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); textedit1 = new QTextEdit; textedit1->setFrameStyle(QFrame::Panel | QFrame::Sunken); textedit1->setReadOnly(TRUE); textedit1->setLineWrapMode(QTextEdit::NoWrap); textedit1->setPlainText( "\n " PROGRAM_NAME " " PROGRAM_VERSION "\n" "\n This program is made by Teunis van Beelen.\n" "\n Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen.\n" "\n Email: teuniz@gmail.com\n" "\n Disclaimer:\n" " Despite this software is intend to be useful, there is no warranty, use this software at your own risk!\n" " EDFbrowser may NOT be used in safety-critical applications, such as life-support medical systems.\n" " The author is NOT responsible for any consequences. For research and educational purpose only.\n"); textedit1->append(str); textedit1->append( "\n This program is licensed by the GPL version 2.\n" "\n This program is free software; you can redistribute it and/or modify\n" " it under the terms of the GNU General Public License as published by\n" " the Free Software Foundation version 2 of the License.\n" " This program is distributed in the hope that it will be useful,\n" " but WITHOUT ANY WARRANTY; without even the implied warranty of\n" " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" " GNU General Public License for more details.\n\n" " GNU GENERAL PUBLIC LICENSE\n" " Version 2, June 1991\n\n" " Copyright (C) 1989, 1991 Free Software Foundation, Inc.,\n" " 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n" " Everyone is permitted to copy and distribute verbatim copies\n" " of this license document, but changing it is not allowed.\n\n" " Preamble\n\n" " The licenses for most software are designed to take away your\n" "freedom to share and change it. By contrast, the GNU General Public\n" "License is intended to guarantee your freedom to share and change free\n" "software--to make sure the software is free for all its users. This\n" "General Public License applies to most of the Free Software\n" "Foundation's software and to any other program whose authors commit to\n" "using it. (Some other Free Software Foundation software is covered by\n" "the GNU Lesser General Public License instead.) You can apply it to\n" "your programs, too.\n"); textedit1->append( " When we speak of free software, we are referring to freedom, not\n" "price. Our General Public Licenses are designed to make sure that you\n" "have the freedom to distribute copies of free software (and charge for\n" "this service if you wish), that you receive source code or can get it\n" "if you want it, that you can change the software or use pieces of it\n" "in new free programs; and that you know you can do these things.\n\n" " To protect your rights, we need to make restrictions that forbid\n" "anyone to deny you these rights or to ask you to surrender the rights.\n" "These restrictions translate to certain responsibilities for you if you\n" "distribute copies of the software, or if you modify it.\n\n" " For example, if you distribute copies of such a program, whether\n" "gratis or for a fee, you must give the recipients all the rights that\n" "you have. You must make sure that they, too, receive or can get the\n" "source code. And you must show them these terms so they know their\n" "rights.\n\n" " We protect your rights with two steps: (1) copyright the software, and\n" "(2) offer you this license which gives you legal permission to copy,\n" "distribute and/or modify the software.\n\n" " Also, for each author's protection and ours, we want to make certain\n" "that everyone understands that there is no warranty for this free\n" "software. If the software is modified by someone else and passed on, we\n" "want its recipients to know that what they have is not the original, so\n" "that any problems introduced by others will not reflect on the original\n" "authors' reputations.\n\n" " Finally, any free program is threatened constantly by software\n" "patents. We wish to avoid the danger that redistributors of a free\n" "program will individually obtain patent licenses, in effect making the\n" "program proprietary. To prevent this, we have made it clear that any\n" "patent must be licensed for everyone's free use or not licensed at all.\n\n" " The precise terms and conditions for copying, distribution and\n" "modification follow.\n\n" " GNU GENERAL PUBLIC LICENSE\n" " TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\n" " 0. This License applies to any program or other work which contains\n" "a notice placed by the copyright holder saying it may be distributed\n" "under the terms of this General Public License. The \"Program\", below,\n" "refers to any such program or work, and a \"work based on the Program\"\n" "means either the Program or any derivative work under copyright law:\n" "that is to say, a work containing the Program or a portion of it,\n" "either verbatim or with modifications and/or translated into another\n" "language. (Hereinafter, translation is included without limitation in\n" "the term \"modification\".) Each licensee is addressed as \"you\".\n\n" "Activities other than copying, distribution and modification are not\n" "covered by this License; they are outside its scope. The act of\n" "running the Program is not restricted, and the output from the Program\n" "is covered only if its contents constitute a work based on the\n" "Program (independent of having been made by running the Program).\n" "Whether that is true depends on what the Program does.\n\n" " 1. You may copy and distribute verbatim copies of the Program's\n" "source code as you receive it, in any medium, provided that you\n" "conspicuously and appropriately publish on each copy an appropriate\n" "copyright notice and disclaimer of warranty; keep intact all the\n" "notices that refer to this License and to the absence of any warranty;\n" "and give any other recipients of the Program a copy of this License\n" "along with the Program.\n\n" "You may charge a fee for the physical act of transferring a copy, and\n" "you may at your option offer warranty protection in exchange for a fee.\n"); textedit1->append( " 2. You may modify your copy or copies of the Program or any portion\n" "of it, thus forming a work based on the Program, and copy and\n" "distribute such modifications or work under the terms of Section 1\n" "above, provided that you also meet all of these conditions:\n\n" " a) You must cause the modified files to carry prominent notices\n" " stating that you changed the files and the date of any change.\n\n" " b) You must cause any work that you distribute or publish, that in\n" " whole or in part contains or is derived from the Program or any\n" " part thereof, to be licensed as a whole at no charge to all third\n" " parties under the terms of this License.\n\n" " c) If the modified program normally reads commands interactively\n" " when run, you must cause it, when started running for such\n" " interactive use in the most ordinary way, to print or display an\n" " announcement including an appropriate copyright notice and a\n" " notice that there is no warranty (or else, saying that you provide\n" " a warranty) and that users may redistribute the program under\n" " these conditions, and telling the user how to view a copy of this\n" " License. (Exception: if the Program itself is interactive but\n" " does not normally print such an announcement, your work based on\n" " the Program is not required to print an announcement.)\n\n" "These requirements apply to the modified work as a whole. If\n" "identifiable sections of that work are not derived from the Program,\n" "and can be reasonably considered independent and separate works in\n" "themselves, then this License, and its terms, do not apply to those\n" "sections when you distribute them as separate works. But when you\n" "distribute the same sections as part of a whole which is a work based\n" "on the Program, the distribution of the whole must be on the terms of\n" "this License, whose permissions for other licensees extend to the\n" "entire whole, and thus to each and every part regardless of who wrote it.\n\n" "Thus, it is not the intent of this section to claim rights or contest\n" "your rights to work written entirely by you; rather, the intent is to\n" "exercise the right to control the distribution of derivative or\n" "collective works based on the Program.\n\n" "In addition, mere aggregation of another work not based on the Program\n" "with the Program (or with a work based on the Program) on a volume of\n" "a storage or distribution medium does not bring the other work under\n" "the scope of this License.\n"); textedit1->append( " 3. You may copy and distribute the Program (or a work based on it,\n" "under Section 2) in object code or executable form under the terms of\n" "Sections 1 and 2 above provided that you also do one of the following:\n\n" " a) Accompany it with the complete corresponding machine-readable\n" " source code, which must be distributed under the terms of Sections\n" " 1 and 2 above on a medium customarily used for software interchange; or,\n\n" " b) Accompany it with a written offer, valid for at least three\n" " years, to give any third party, for a charge no more than your\n" " cost of physically performing source distribution, a complete\n" " machine-readable copy of the corresponding source code, to be\n" " distributed under the terms of Sections 1 and 2 above on a medium\n" " customarily used for software interchange; or,\n\n" " c) Accompany it with the information you received as to the offer\n" " to distribute corresponding source code. (This alternative is\n" " allowed only for noncommercial distribution and only if you\n" " received the program in object code or executable form with such\n" " an offer, in accord with Subsection b above.)\n\n" "The source code for a work means the preferred form of the work for\n" "making modifications to it. For an executable work, complete source\n" "code means all the source code for all modules it contains, plus any\n" "associated interface definition files, plus the scripts used to\n" "control compilation and installation of the executable. However, as a\n" "special exception, the source code distributed need not include\n" "anything that is normally distributed (in either source or binary\n" "form) with the major components (compiler, kernel, and so on) of the\n" "operating system on which the executable runs, unless that component\n" "itself accompanies the executable.\n\n" "If distribution of executable or object code is made by offering\n" "access to copy from a designated place, then offering equivalent\n" "access to copy the source code from the same place counts as\n" "distribution of the source code, even though third parties are not\n" "compelled to copy the source along with the object code.\n"); textedit1->append( " 4. You may not copy, modify, sublicense, or distribute the Program\n" "except as expressly provided under this License. Any attempt\n" "otherwise to copy, modify, sublicense or distribute the Program is\n" "void, and will automatically terminate your rights under this License.\n" "However, parties who have received copies, or rights, from you under\n" "this License will not have their licenses terminated so long as such\n" "parties remain in full compliance.\n\n" " 5. You are not required to accept this License, since you have not\n" "signed it. However, nothing else grants you permission to modify or\n" "distribute the Program or its derivative works. These actions are\n" "prohibited by law if you do not accept this License. Therefore, by\n" "modifying or distributing the Program (or any work based on the\n" "Program), you indicate your acceptance of this License to do so, and\n" "all its terms and conditions for copying, distributing or modifying\n" "the Program or works based on it.\n\n" " 6. Each time you redistribute the Program (or any work based on the\n" "Program), the recipient automatically receives a license from the\n" "original licensor to copy, distribute or modify the Program subject to\n" "these terms and conditions. You may not impose any further\n" "restrictions on the recipients' exercise of the rights granted herein.\n" "You are not responsible for enforcing compliance by third parties to\n" "this License.\n\n" " 7. If, as a consequence of a court judgment or allegation of patent\n" "infringement or for any other reason (not limited to patent issues),\n" "conditions are imposed on you (whether by court order, agreement or\n" "otherwise) that contradict the conditions of this License, they do not\n" "excuse you from the conditions of this License. If you cannot\n" "distribute so as to satisfy simultaneously your obligations under this\n" "License and any other pertinent obligations, then as a consequence you\n" "may not distribute the Program at all. For example, if a patent\n" "license would not permit royalty-free redistribution of the Program by\n" "all those who receive copies directly or indirectly through you, then\n" "the only way you could satisfy both it and this License would be to\n" "refrain entirely from distribution of the Program.\n\n" "If any portion of this section is held invalid or unenforceable under\n" "any particular circumstance, the balance of the section is intended to\n" "apply and the section as a whole is intended to apply in other\n" "circumstances.\n\n" "It is not the purpose of this section to induce you to infringe any\n" "patents or other property right claims or to contest validity of any\n" "such claims; this section has the sole purpose of protecting the\n" "integrity of the free software distribution system, which is\n" "implemented by public license practices. Many people have made\n" "generous contributions to the wide range of software distributed\n" "through that system in reliance on consistent application of that\n" "system; it is up to the author/donor to decide if he or she is willing\n" "to distribute software through any other system and a licensee cannot\n" "impose that choice.\n\n" "This section is intended to make thoroughly clear what is believed to\n" "be a consequence of the rest of this License.\n\n"); textedit1->append( " 8. If the distribution and/or use of the Program is restricted in\n" "certain countries either by patents or by copyrighted interfaces, the\n" "original copyright holder who places the Program under this License\n" "may add an explicit geographical distribution limitation excluding\n" "those countries, so that distribution is permitted only in or among\n" "countries not thus excluded. In such case, this License incorporates\n" "the limitation as if written in the body of this License.\n\n" " 9. The Free Software Foundation may publish revised and/or new versions\n" "of the General Public License from time to time. Such new versions will\n" "be similar in spirit to the present version, but may differ in detail to\n" "address new problems or concerns.\n\n" "Each version is given a distinguishing version number. If the Program\n" "specifies a version number of this License which applies to it and \"any\n" "later version\", you have the option of following the terms and conditions\n" "either of that version or of any later version published by the Free\n" "Software Foundation. If the Program does not specify a version number of\n" "this License, you may choose any version ever published by the Free Software\n" "Foundation.\n\n" " 10. If you wish to incorporate parts of the Program into other free\n" "programs whose distribution conditions are different, write to the author\n" "to ask for permission. For software which is copyrighted by the Free\n" "Software Foundation, write to the Free Software Foundation; we sometimes\n" "make exceptions for this. Our decision will be guided by the two goals\n" "of preserving the free status of all derivatives of our free software and\n" "of promoting the sharing and reuse of software generally.\n\n" " NO WARRANTY\n\n" " 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\n" "FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN\n" "OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\n" "PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\n" "OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n" "MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS\n" "TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE\n" "PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\n" "REPAIR OR CORRECTION.\n\n" " 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\n" "WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\n" "REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\n" "INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\n" "OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\n" "TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\n" "YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\n" "PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\n" "POSSIBILITY OF SUCH DAMAGES.\n\n" " END OF TERMS AND CONDITIONS\n\n"); pushButton1 = new QPushButton; pushButton1->setText("Close"); hlayout1 = new QHBoxLayout; hlayout1->insertStretch(0, 100); hlayout1->addWidget(pushButton1); vlayout1 = new QVBoxLayout; vlayout1->addWidget(textedit1); vlayout1->setStretchFactor(textedit1, 100); vlayout1->addLayout(hlayout1); vlayout1->setStretchFactor(hlayout1, 0); AboutDialog->setLayout(vlayout1); QObject::connect(pushButton1, SIGNAL(clicked()), AboutDialog, SLOT(close())); AboutDialog->exec(); } edfbrowser_153_source/PaxHeaders.2978/save_annots.cpp0000644000175000001440000000013212251654530021173 xustar000000000000000030 mtime=1386699096.479032511 30 atime=1386699096.479032511 30 ctime=1386699096.479032511 edfbrowser_153_source/save_annots.cpp0000644000175000001440000003447612251654530020742 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "save_annots.h" #if defined(__APPLE__) || defined(__MACH__) || defined(__APPLE_CC__) #define fopeno fopen #else #define fseeko fseeko64 #define ftello ftello64 #define fopeno fopen64 #endif int save_annotations(UI_Mainwindow *mainwindow, FILE *outputfile, struct edfhdrblock *hdr, struct annotationblock *annotlist) { int i, j, k, n, p=0, new_edfsignals=0, signalslist[MAXSIGNALS], datarecords, annot_len, annot_smp_per_record, annot_recordsize, timestamp_decimals, timestamp_digits, annots_per_datrec, space, progress_steps; char *readbuf, scratchpad[256], *annot_buf; long long time; FILE *inputfile; struct annotationblock *annot; inputfile = hdr->file_hdl; for(i=0; iedfsignals; i++) { if(!hdr->edfparam[i].annotation) { signalslist[new_edfsignals] = i; new_edfsignals++; } } datarecords = hdr->datarecords; time = (hdr->datarecords * hdr->long_data_record_duration) / TIME_DIMENSION; timestamp_decimals = get_tal_timestamp_decimal_cnt(hdr); if(timestamp_decimals < 0) { return(1); } timestamp_digits = get_tal_timestamp_digit_cnt(hdr); if(timestamp_digits < 0) { return(1); } annot = annotlist; annot_len = get_max_annotation_strlen(&annot); i = edfplus_annotation_count(&annot); annots_per_datrec = i / datarecords; if(i % datarecords) { annots_per_datrec++; } annot_recordsize = (annot_len * annots_per_datrec) + timestamp_digits + timestamp_decimals + 4; if(timestamp_decimals) { annot_recordsize++; } if(hdr->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; } } readbuf = (char *)malloc(hdr->recordsize); if(readbuf==NULL) { return(1); } annot_buf = (char *)malloc(annot_recordsize + 10); if(annot_buf==NULL) { free(readbuf); return(1); } /////////////////////////////////////////////////////////////////// rewind(outputfile); if(hdr->edf) { fprintf(outputfile, "0 "); } else { fprintf(outputfile, "XBIOSEMI"); rewind(outputfile); fputc(255, outputfile); fseeko(outputfile, 0LL, SEEK_END); } fseeko(inputfile, 8LL, SEEK_SET); if((hdr->edfplus)||(hdr->bdfplus)) { if(fread(scratchpad, 176, 1, inputfile)!=1) { free(readbuf); free(annot_buf); return(2); } if((hdr->genuine_nk) && (hdr->nk_triggers_read)) { space = 0; for(n=80; n<160; n++) { if(scratchpad[n] == ' ') { space++; if(space > 3) { break; } } } n += 14; if(n<150) { if(!strncmp(scratchpad + n, "EEG", 3)) { scratchpad[n] = 'e'; scratchpad[n+1] = 'e'; scratchpad[n+2] = 'g'; } } } if(fwrite(scratchpad, 176, 1, outputfile)!=1) { free(readbuf); free(annot_buf); return(3); } } else { sprintf(scratchpad, "X X X X "); if(fread(scratchpad + 8, 80, 1, inputfile)!=1) { free(readbuf); free(annot_buf); return(2); } if(fwrite(scratchpad, 80, 1, outputfile)!=1) { free(readbuf); free(annot_buf); return(3); } sprintf(scratchpad, "Startdate X X X X "); if(fread(scratchpad + 18, 80, 1, inputfile)!=1) { free(readbuf); free(annot_buf); return(2); } if(fwrite(scratchpad, 80, 1, outputfile)!=1) { free(readbuf); free(annot_buf); return(3); } if(fread(scratchpad, 16, 1, inputfile)!=1) { free(readbuf); free(annot_buf); return(2); } if(fwrite(scratchpad, 16, 1, outputfile)!=1) { free(readbuf); free(annot_buf); return(3); } } fprintf(outputfile, "%-8i", (new_edfsignals * 256) + 512); if(hdr->edf) { fprintf(outputfile, "EDF+C"); } else { fprintf(outputfile, "BDF+C"); } for(i=0; i<39; i++) { fputc(' ', outputfile); } fprintf(outputfile, "%-8i", datarecords); snprintf(scratchpad, 256, "%.12f", hdr->data_record_duration); remove_trailing_zeros(scratchpad); strcat(scratchpad, " "); if((!strncmp(scratchpad, "0.", 2)) && (scratchpad[8] != ' ')) { scratchpad[9] = 0; fprintf(outputfile, "%s", scratchpad + 1); } else { scratchpad[8] = 0; fprintf(outputfile, "%s", scratchpad); } fprintf(outputfile, "%-4i", new_edfsignals + 1); for(i=0; iedfparam[signalslist[i]].label); } if(hdr->edf) { fprintf(outputfile, "%s", "EDF Annotations "); } else { fprintf(outputfile, "%s", "BDF Annotations "); } for(i=0; iedfparam[signalslist[i]].transducer); } for(i=0; i<80; i++) { fputc(' ', outputfile); } for(i=0; iedfparam[signalslist[i]].physdimension); } for(i=0; i<8; i++) { fputc(' ', outputfile); } for(i=0; iedfparam[signalslist[i]].phys_min); for(k=0; k<8; k++) { if(scratchpad[k]=='.') { for(j=7; j>=0; j--) { if((scratchpad[j]!='.')&&(scratchpad[j]!='0')) { break; } if(scratchpad[j]=='.') { scratchpad[j] = ' '; break; } scratchpad[j] = ' '; } break; } scratchpad[8] = 0; } fprintf(outputfile, "%s", scratchpad); } fprintf(outputfile, "-1 "); for(i=0; iedfparam[signalslist[i]].phys_max); for(k=0; k<8; k++) { if(scratchpad[k]=='.') { for(j=7; j>=0; j--) { if((scratchpad[j]!='.')&&(scratchpad[j]!='0')) { break; } if(scratchpad[j]=='.') { scratchpad[j] = ' '; break; } scratchpad[j] = ' '; } break; } } scratchpad[8] = 0; fprintf(outputfile, "%s", scratchpad); } fprintf(outputfile, "1 "); for(i=0; iedfparam[signalslist[i]].dig_min); } if(hdr->edf) { fprintf(outputfile, "%s", "-32768 "); } else { fprintf(outputfile, "%s", "-8388608"); } for(i=0; iedfparam[signalslist[i]].dig_max); } if(hdr->edf) { fprintf(outputfile, "%s", "32767 "); } else { fprintf(outputfile, "%s", "8388607 "); } for(i=0; iedfparam[signalslist[i]].prefilter); } for(i=0; i<80; i++) { fputc(' ', outputfile); } for(i=0; iedfparam[signalslist[i]].smp_per_record); } fprintf(outputfile, "%-8i", annot_smp_per_record); for(i=0; i<((new_edfsignals * 32) + 32); i++) { fputc(' ', outputfile); } /////////////////////////////////////////////////////////////////// QProgressDialog progress("Saving file...", "Abort", 0, datarecords, mainwindow); progress.setWindowModality(Qt::WindowModal); progress.setMinimumDuration(200); progress_steps = datarecords / 100; if(progress_steps < 1) { progress_steps = 1; } fseeko(inputfile, (long long)(hdr->hdrsize), SEEK_SET); annot = annotlist; time = hdr->starttime_offset; for(k=0; kprocessEvents(); if(progress.wasCanceled() == TRUE) { free(readbuf); free(annot_buf); return(4); } } if(fread(readbuf, hdr->recordsize, 1, inputfile) != 1) { free(readbuf); free(annot_buf); return(2); } if(hdr->edf) { for(i=0; iedfparam[signalslist[i]].smp_per_record; j++) { fputc(*((unsigned char *)(readbuf + hdr->edfparam[signalslist[i]].buf_offset + (j * 2))), outputfile); fputc(*((unsigned char *)(readbuf + hdr->edfparam[signalslist[i]].buf_offset + (j * 2) + 1)), outputfile); } } } else { for(i=0; iedfparam[signalslist[i]].smp_per_record; j++) { fputc(*((unsigned char *)(readbuf + hdr->edfparam[signalslist[i]].buf_offset + (j * 3))), outputfile); fputc(*((unsigned char *)(readbuf + hdr->edfparam[signalslist[i]].buf_offset + (j * 3) + 1)), outputfile); fputc(*((unsigned char *)(readbuf + hdr->edfparam[signalslist[i]].buf_offset + (j * 3) + 2)), outputfile); } } } #ifdef Q_WS_WIN switch(timestamp_decimals) { case 0 : p = snprintf(annot_buf, 16, "+%I64d", time / TIME_DIMENSION); break; case 1 : p = snprintf(annot_buf, 16, "+%I64d.%01I64d", time / TIME_DIMENSION, (time % TIME_DIMENSION) / 1000000LL); break; case 2 : p = snprintf(annot_buf, 16, "+%I64d.%02I64d", time / TIME_DIMENSION, (time % TIME_DIMENSION) / 100000LL); break; case 3 : p = snprintf(annot_buf, 16, "+%I64d.%03I64d", time / TIME_DIMENSION, (time % TIME_DIMENSION) / 10000LL); break; case 4 : p = snprintf(annot_buf, 16, "+%I64d.%04I64d", time / TIME_DIMENSION, (time % TIME_DIMENSION) / 1000LL); break; case 5 : p = snprintf(annot_buf, 16, "+%I64d.%05I64d", time / TIME_DIMENSION, (time % TIME_DIMENSION) / 100LL); break; case 6 : p = snprintf(annot_buf, 16, "+%I64d.%06I64d", time / TIME_DIMENSION, (time % TIME_DIMENSION) / 10LL); break; case 7 : p = snprintf(annot_buf, 16, "+%I64d.%07I64d", time / TIME_DIMENSION, time % TIME_DIMENSION); break; } #else switch(timestamp_decimals) { case 0 : p = snprintf(annot_buf, 16, "+%lli", time / TIME_DIMENSION); break; case 1 : p = snprintf(annot_buf, 16, "+%lli.%01lli", time / TIME_DIMENSION, (time % TIME_DIMENSION) / 1000000LL); break; case 2 : p = snprintf(annot_buf, 16, "+%lli.%02lli", time / TIME_DIMENSION, (time % TIME_DIMENSION) / 100000LL); break; case 3 : p = snprintf(annot_buf, 16, "+%lli.%03lli", time / TIME_DIMENSION, (time % TIME_DIMENSION) / 10000LL); break; case 4 : p = snprintf(annot_buf, 16, "+%lli.%04lli", time / TIME_DIMENSION, (time % TIME_DIMENSION) / 1000LL); break; case 5 : p = snprintf(annot_buf, 16, "+%lli.%05lli", time / TIME_DIMENSION, (time % TIME_DIMENSION) / 100LL); break; case 6 : p = snprintf(annot_buf, 16, "+%lli.%06lli", time / TIME_DIMENSION, (time % TIME_DIMENSION) / 10LL); break; case 7 : p = snprintf(annot_buf, 16, "+%lli.%07lli", time / TIME_DIMENSION, time % TIME_DIMENSION); break; } #endif annot_buf[p++] = 20; annot_buf[p++] = 20; annot_buf[p++] = 0; if(annot!=NULL) { for(i=0; ionset<0) { #ifdef Q_WS_WIN p += snprintf(annot_buf + p, 20, "-%I64d.%07I64d", -(annot->onset / TIME_DIMENSION), -(annot->onset % TIME_DIMENSION)); #else p += snprintf(annot_buf + p, 20, "-%lli.%07lli", -(annot->onset / TIME_DIMENSION), -(annot->onset % TIME_DIMENSION)); #endif } else { #ifdef Q_WS_WIN p += snprintf(annot_buf + p, 20, "+%I64d.%07I64d", annot->onset / TIME_DIMENSION, annot->onset % TIME_DIMENSION); #else p += snprintf(annot_buf + p, 20, "+%lli.%07lli", annot->onset / TIME_DIMENSION, annot->onset % TIME_DIMENSION); #endif } for(j=0; j<7; j++) { if(annot_buf[p - j - 1] != '0') { break; } } if(j) { p -= j; if(j == 7) { p--; } } if(annot->duration[0]) { annot_buf[p++] = 21; p += sprintf(annot_buf + p, "%s", annot->duration); } annot_buf[p++] = 20; p += sprintf(annot_buf + p, "%s", annot->annotation); annot_buf[p++] = 20; annot_buf[p++] = 0; annot = annot->next_annotation; } } } for(; plong_data_record_duration; } progress.reset(); free(readbuf); free(annot_buf); return(0); } edfbrowser_153_source/PaxHeaders.2978/view_montage_dialog.cpp0000644000175000001440000000013212251654530022656 xustar000000000000000030 mtime=1386699096.479032511 30 atime=1386699096.479032511 30 ctime=1386699096.479032511 edfbrowser_153_source/view_montage_dialog.cpp0000644000175000001440000005226312251654530022417 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "view_montage_dialog.h" UI_ViewMontagewindow::UI_ViewMontagewindow(QWidget *w_parent) { mainwindow = (UI_Mainwindow *)w_parent; mtg_path[0] = 0; mtg_dir[0] = 0; if(mainwindow->recent_montagedir[0]!=0) { strcpy(mtg_dir, mainwindow->recent_montagedir); } ViewMontageDialog = new QDialog; ViewMontageDialog->setMinimumSize(QSize(500, 300)); ViewMontageDialog->resize(500, 440); ViewMontageDialog->setWindowTitle("View montage"); ViewMontageDialog->setModal(TRUE); ViewMontageDialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); t_model = new QStandardItemModel(this); tree = new QTreeView; tree->setHeaderHidden(TRUE); tree->setIndentation(30); tree->setSelectionMode(QAbstractItemView::NoSelection); tree->setEditTriggers(QAbstractItemView::NoEditTriggers); tree->setSortingEnabled(FALSE); tree->setDragDropMode(QAbstractItemView::NoDragDrop); tree->setModel(t_model); SelectButton = new QPushButton; SelectButton->setFixedSize(100, 25); SelectButton->setText("Select montage"); CloseButton = new QPushButton; CloseButton->setFixedSize(100, 25); CloseButton->setText("Close"); hbox = new QHBoxLayout; hbox->addWidget(SelectButton, 0, Qt::AlignLeft); hbox->addWidget(CloseButton, 0, Qt::AlignRight); box = new QBoxLayout(QBoxLayout::TopToBottom, ViewMontageDialog); box->addWidget(tree); box->addLayout(hbox); QObject::connect(CloseButton, SIGNAL(clicked()), ViewMontageDialog, SLOT(close())); QObject::connect(SelectButton, SIGNAL(clicked()), this, SLOT(SelectButtonClicked())); ViewMontageDialog->exec(); } void UI_ViewMontagewindow::SelectButtonClicked() { int signalcomps_read=0, signals_read, signal_cnt, filters_read, color, filter_cnt=0, ravg_filter_cnt=0, fidfilter_cnt=0, islpf, factor[MAXSIGNALS], signalcomps, screen_offset, order, model, type, size, polarity=1; char *result, composition_txt[2048], label[256]; double frequency, frequency2, voltpercm, ripple, timescale, d_tmp; QStandardItem *parentItem, *signalItem, *filterItem; struct xml_handle *xml_hdl; strcpy(mtg_path, QFileDialog::getOpenFileName(0, "Choose a montage", QString::fromLocal8Bit(mtg_dir), "Montage files (*.mtg *.MTG)").toLocal8Bit().data()); if(!strcmp(mtg_path, "")) { return; } get_directory_from_path(mtg_dir, mtg_path, MAX_PATH_LENGTH); xml_hdl = xml_get_handle(mtg_path); if(xml_hdl==NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not open file for reading."); messagewindow.exec(); return; } if(strcmp(xml_hdl->elementname, PROGRAM_NAME "_montage")) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There seems to be an error in this montage file."); messagewindow.exec(); xml_close(xml_hdl); return; } ViewMontageDialog->setWindowTitle(mtg_path); t_model->clear(); parentItem = t_model->invisibleRootItem(); for(signalcomps=0; ; signalcomps++) { xml_goto_root(xml_hdl); signals_read = 0; filter_cnt = 0; ravg_filter_cnt = 0; fidfilter_cnt = 0; if(xml_goto_nth_element_inside(xml_hdl, "signalcomposition", signalcomps_read)) { break; } if(xml_goto_nth_element_inside(xml_hdl, "num_of_signals", 0)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There seems to be an error in this montage file."); messagewindow.exec(); xml_close(xml_hdl); return; } result = xml_get_content_of_element(xml_hdl); signal_cnt = atoi(result); free(result); if((signal_cnt<1)||(signal_cnt>256)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There seems to be an error in this montage file."); messagewindow.exec(); xml_close(xml_hdl); return; } xml_go_up(xml_hdl); if(xml_goto_nth_element_inside(xml_hdl, "voltpercm", 0)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There seems to be an error in this montage file."); messagewindow.exec(); xml_close(xml_hdl); return; } result = xml_get_content_of_element(xml_hdl); voltpercm = atof(result); free(result); xml_go_up(xml_hdl); if(xml_goto_nth_element_inside(xml_hdl, "screen_offset", 0)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There seems to be an error in this montage file."); messagewindow.exec(); xml_close(xml_hdl); return; } result = xml_get_content_of_element(xml_hdl); screen_offset = atoi(result); free(result); xml_go_up(xml_hdl); if(!(xml_goto_nth_element_inside(xml_hdl, "polarity", 0))) { result = xml_get_content_of_element(xml_hdl); polarity = atoi(result); if(polarity != -1) { polarity = 1; } free(result); xml_go_up(xml_hdl); } if(xml_goto_nth_element_inside(xml_hdl, "color", 0)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There seems to be an error in this montage file."); messagewindow.exec(); xml_close(xml_hdl); return; } result = xml_get_content_of_element(xml_hdl); color = atoi(result); free(result); xml_go_up(xml_hdl); if(!(xml_goto_nth_element_inside(xml_hdl, "filter_cnt", 0))) { result = xml_get_content_of_element(xml_hdl); filter_cnt = atoi(result); free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "ravg_filter_cnt", 0))) { result = xml_get_content_of_element(xml_hdl); ravg_filter_cnt = atoi(result); free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "fidfilter_cnt", 0))) { result = xml_get_content_of_element(xml_hdl); fidfilter_cnt = atoi(result); free(result); xml_go_up(xml_hdl); } composition_txt[0] = 0; if(!(xml_goto_nth_element_inside(xml_hdl, "alias", 0))) { result = xml_get_content_of_element(xml_hdl); if(result[0] != 0) { strcpy(composition_txt, "alias: "); strcat(composition_txt, result); strcat(composition_txt, " "); } free(result); xml_go_up(xml_hdl); } for(signals_read=0; signals_readappendRow(signalItem); sprintf(composition_txt, "amplitude: %f", voltpercm); remove_trailing_zeros(composition_txt); sprintf(composition_txt + strlen(composition_txt), "/cm offset: %f", (double)screen_offset * mainwindow->pixelsizefactor * voltpercm); remove_trailing_zeros(composition_txt); strcat(composition_txt, " color: "); switch(color) { case Qt::white : strcat(composition_txt, "white"); break; case Qt::black : strcat(composition_txt, "black"); break; case Qt::red : strcat(composition_txt, "red"); break; case Qt::darkRed : strcat(composition_txt, "dark red"); break; case Qt::green : strcat(composition_txt, "green"); break; case Qt::darkGreen : strcat(composition_txt, "dark green"); break; case Qt::blue : strcat(composition_txt, "blue"); break; case Qt::darkBlue : strcat(composition_txt, "dark blue"); break; case Qt::cyan : strcat(composition_txt, "cyan"); break; case Qt::darkCyan : strcat(composition_txt, "dark cyan"); break; case Qt::magenta : strcat(composition_txt, "magenta"); break; case Qt::darkMagenta : strcat(composition_txt, "dark magenta"); break; case Qt::yellow : strcat(composition_txt, "yellow"); break; case Qt::darkYellow : strcat(composition_txt, "dark yellow"); break; case Qt::gray : strcat(composition_txt, "gray"); break; case Qt::darkGray : strcat(composition_txt, "dark gray"); break; case Qt::lightGray : strcat(composition_txt, "light gray"); break; } signalItem->appendRow(new QStandardItem(composition_txt)); filterItem = new QStandardItem("Filters"); signalItem->appendRow(filterItem); for(filters_read=0; filters_readappendRow(new QStandardItem(composition_txt)); xml_go_up(xml_hdl); xml_go_up(xml_hdl); } for(filters_read=0; filters_readappendRow(new QStandardItem(composition_txt)); xml_go_up(xml_hdl); xml_go_up(xml_hdl); } for(filters_read=0; filters_readappendRow(new QStandardItem(composition_txt)); xml_go_up(xml_hdl); xml_go_up(xml_hdl); } if(!xml_goto_nth_element_inside(xml_hdl, "ecg_filter", 0)) { if(xml_goto_nth_element_inside(xml_hdl, "type", 0)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There seems to be an error in this montage file."); messagewindow.exec(); xml_close(xml_hdl); return; } result = xml_get_content_of_element(xml_hdl); type = atoi(result); free(result); if(type == 1) { sprintf(composition_txt, "ECG heartrate detection"); } filterItem->appendRow(new QStandardItem(composition_txt)); xml_go_up(xml_hdl); xml_go_up(xml_hdl); } if(!xml_goto_nth_element_inside(xml_hdl, "zratio_filter", 0)) { if(xml_goto_nth_element_inside(xml_hdl, "type", 0)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There seems to be an error in this montage file."); messagewindow.exec(); xml_close(xml_hdl); return; } result = xml_get_content_of_element(xml_hdl); type = atoi(result); free(result); xml_go_up(xml_hdl); if(type == 1) { if(xml_goto_nth_element_inside(xml_hdl, "crossoverfreq", 0)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There seems to be an error in this montage file."); messagewindow.exec(); xml_close(xml_hdl); return; } result = xml_get_content_of_element(xml_hdl); d_tmp = atof(result); free(result); sprintf(composition_txt, "Z-ratio cross-over frequency is %.1f", d_tmp); } filterItem->appendRow(new QStandardItem(composition_txt)); xml_go_up(xml_hdl); xml_go_up(xml_hdl); } signalcomps_read++; } xml_goto_root(xml_hdl); if(!(xml_goto_nth_element_inside(xml_hdl, "pagetime", 0))) { result = xml_get_content_of_element(xml_hdl); timescale = atof(result); timescale /= TIME_DIMENSION; sprintf(composition_txt, "timescale: %f seconds", timescale); remove_trailing_zeros(composition_txt); free(result); parentItem->appendRow(new QStandardItem(composition_txt)); } xml_close(xml_hdl); } edfbrowser_153_source/PaxHeaders.2978/print_to_bdf.h0000644000175000001440000000013212251654530020771 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/print_to_bdf.h0000644000175000001440000000322512251654530020524 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef PRINT_SCREEN_TO_BDF_H #define PRINT_SCREEN_TO_BDF_H #include #include #include #include #include #include #include #include #include "global.h" #include "mainwindow.h" #include "popup_messagewindow.h" #include "filter.h" #include "utc_date_time.h" #include "third_party/fidlib/fidlib.h" class UI_Mainwindow; void print_screen_to_bdf(UI_Mainwindow *); #endif // PRINT_SCREEN_TO_BDF_H edfbrowser_153_source/PaxHeaders.2978/reduce_signals.h0000644000175000001440000000013212251654530021307 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/reduce_signals.h0000644000175000001440000000601212251654530021037 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef UI_REDUCESIGNALSFORM_H #define UI_REDUCESIGNALSFORM_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "mainwindow.h" #include "check_edf_file.h" #include "popup_messagewindow.h" #include "utils.h" #include "utc_date_time.h" #include "active_file_chooser.h" #include "edf_annot_list.h" class UI_Mainwindow; class UI_ReduceSignalsWindow : public QObject { Q_OBJECT public: UI_ReduceSignalsWindow(QWidget *parent); UI_Mainwindow *mainwindow; private: QLabel *label1, *label2, *label3, *label4, *label5; QPushButton *pushButton1, *pushButton2, *pushButton3, *pushButton4, *pushButton5, *pushButton6; QSpinBox *spinBox1, *spinBox2, *spinBox3; QRadioButton *radioButton1, *radioButton2; QTableWidget *SignalsTablewidget; QDialog *myobjectDialog; int signalslist[MAXSIGNALS], dividerlist[MAXSIGNALS], file_num; char inputpath[MAX_PATH_LENGTH], outputpath[MAX_PATH_LENGTH], *recent_savedir; FILE *inputfile, *outputfile; struct edfhdrblock *edfhdr; void showpopupmessage(const char *, const char *); private slots: void SelectFileButton(); void StartConversion(); void Select_all_signals(); void Deselect_all_signals(); void Set_SRdivider_all_signals(); void spinBox1changed(int); void spinBox2changed(int); void radioButton1Toggled(bool); void radioButton2Toggled(bool); }; #endif edfbrowser_153_source/PaxHeaders.2978/averager_curve_wnd.h0000644000175000001440000000012712251654530022174 xustar000000000000000029 mtime=1386699096.46603258 29 atime=1386699096.46603258 29 ctime=1386699096.46603258 edfbrowser_153_source/averager_curve_wnd.h0000644000175000001440000000615012251654530021723 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef AVERAGERCURVEWND_H #define AVERAGERCURVEWND_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "mainwindow.h" #include "signalcurve.h" #include "edflib.h" #include "utils.h" #include "flywheel.h" class UI_Mainwindow; class UI_AverageCurveWindow : public QWidget { Q_OBJECT public: UI_AverageCurveWindow(struct signalcompblock *, QWidget *, int, double *, double, double, long long, long long, int, int, char *, double); ~UI_AverageCurveWindow(); UI_Mainwindow *mainwindow; QDialog *averager_curve_dialog; struct signalcompblock *signalcomp; private: int averager_curve_dialog_is_destroyed, averagecurvedialognumber, avg_cnt, avg_trigger_position_ratio, flywheel_value; double pagetime, *avgbuf, avg_max_value, avg_min_value, avg_period; long long avg_samples_on_screen; char avg_annotation[MAX_ANNOTATION_LEN + 1]; QHBoxLayout *hlayout1, *hlayout2, *hlayout3, *hlayout4; QVBoxLayout *vlayout1, *vlayout2, *vlayout3; SignalCurve *curve1; QSlider *amplitudeSlider, *spanSlider, *centerSlider; QLabel *spanLabel, *centerLabel, *amplitudeLabel; QCheckBox *inversionCheckBox, *BWCheckBox; UI_Flywheel *flywheel1; private slots: void sliderMoved(int); void averager_curve_dialogDestroyed(QObject *); void export_edf(void); void update_flywheel(int); }; #endif edfbrowser_153_source/PaxHeaders.2978/filter.cpp0000644000175000001440000000013212251654530020140 xustar000000000000000030 mtime=1386699096.477032522 30 atime=1386699096.477032522 30 ctime=1386699096.477032522 edfbrowser_153_source/filter.cpp0000644000175000001440000000661312251654530017677 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * The current version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "filter.h" struct filter_settings * create_filter(int is_LPF, double cutoff_frequency, double sample_frequency) { struct filter_settings *settings; settings = (struct filter_settings *) calloc(1, sizeof(struct filter_settings)); if(settings==NULL) return(NULL); settings->is_LPF = is_LPF; settings->cutoff_frequency = cutoff_frequency; settings->sample_frequency = sample_frequency; settings->factor = get_filter_factor(cutoff_frequency, sample_frequency); settings->old_input = 0.0; settings->old_output = 0.0; settings->first_sample = 1; return(settings); } struct filter_settings * create_filter_copy(struct filter_settings *src) { struct filter_settings *settings; settings = (struct filter_settings *)calloc(1, sizeof(struct filter_settings)); if(settings==NULL) { return(NULL); } memcpy(settings, src, sizeof(struct filter_settings)); return(settings); } void reset_filter(int offset, struct filter_settings *settings) { settings->first_sample = 0; settings->old_input = offset; if(settings->is_LPF) { settings->old_output = offset; } else { settings->old_output = 0.0; } } int first_order_filter(int new_input, struct filter_settings *settings) { double new_output; if(settings->first_sample) { settings->first_sample = 0; settings->old_input = new_input; if(settings->is_LPF) { settings->old_output = new_input; return(new_input); } else { settings->old_output = 0.0; return(0); } } if(settings->is_LPF) { new_output = settings->old_output + ((settings->old_input - settings->old_output) * settings->factor); } else { new_output = settings->old_output * (1.0 - settings->factor); new_output += new_input - settings->old_input; } settings->old_input = new_input; settings->old_output = new_output; return((int)new_output); } double get_filter_factor(double cutoff_frequency, double sample_frequency) { double t; t = (cutoff_frequency * 2.0 * M_PI) / sample_frequency; t = exp(-t); t = 1.0 - t; // now t will be in the range 0.001 (at high sample-frequency and low cut-off) // to 0.999 (at low sample-frequency and high cut-off) return(t); } edfbrowser_153_source/PaxHeaders.2978/jump_dialog.h0000644000175000001440000000013212251654530020612 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/jump_dialog.h0000644000175000001440000000435012251654530020345 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef JUMPMENUFORM1_H #define JUMPMENUFORM1_H #include #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "mainwindow.h" #include "popup_messagewindow.h" class UI_Mainwindow; class UI_JumpMenuDialog : public QObject { Q_OBJECT public: UI_JumpMenuDialog(QWidget *parent=0); UI_Mainwindow *mainwindow; private: QDialog *jump_dialog; QPushButton *CloseButton, *jumpButton; QLabel *label1, *label2, *label3; QTimeEdit *timeEdit1, *timeEdit2; QTime time1, time2; QSpinBox *daybox1, *daybox2; long long recording_duration, starttime; private slots: void jumpbutton_pressed(); void absolutetime_changed(const QTime &); void offsettime_changed(const QTime &); void absoluteday_changed(int); void offsetday_changed(int); }; #endif // JUMPMENUFORM1_H edfbrowser_153_source/PaxHeaders.2978/statistics_dialog.cpp0000644000175000001440000000013212251654530022364 xustar000000000000000030 mtime=1386699096.479032511 30 atime=1386699096.479032511 30 ctime=1386699096.479032511 edfbrowser_153_source/statistics_dialog.cpp0000644000175000001440000002730112251654530022120 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "statistics_dialog.h" UI_StatisticWindow::UI_StatisticWindow(struct signalcompblock *signalcomp, long long pagetime) { int i, tmp, NN50, pNN50; char stat_str[2048]; double d_tmp, average_bpm, average_rr, sdnn_bpm, sdnn_rr, *buf_bpm, rmssd_rr, *beat_interval_list; StatDialog = new QDialog; StatDialog->setWindowTitle("Statistics"); StatDialog->setModal(TRUE); StatDialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); StatDialog->setWindowFlags(Qt::Window | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint); StatDialog->setWindowIcon(QIcon(":/images/edf.png")); if(signalcomp->ecg_filter != NULL) { StatDialog->setMinimumSize(600, 400); StatDialog->setSizeGripEnabled(TRUE); startSlider = new QSlider; startSlider->setOrientation(Qt::Horizontal); startSlider->setMinimum(0); startSlider->setMaximum(295); startSlider->setValue(0); stopSlider = new QSlider; stopSlider->setOrientation(Qt::Horizontal); stopSlider->setMinimum(5); stopSlider->setMaximum(300); stopSlider->setValue(300); curve1 = new SignalCurve(StatDialog); curve1->setSignalColor(Qt::darkGreen); curve1->setBackgroundColor(Qt::black); curve1->setRasterColor(Qt::gray); curve1->setTraceWidth(0); curve1->setH_label(signalcomp->physdimension); curve1->setLowerLabel("HR (beats/min)"); curve1->setDashBoardEnabled(FALSE); curve1->setUpperLabel1("Distribution"); curve1->setFillSurfaceEnabled(TRUE); vlayout2_1 = new QVBoxLayout; vlayout2_1->setSpacing(20); vlayout2_1->addWidget(curve1); vlayout2_1->addWidget(startSlider); vlayout2_1->addWidget(stopSlider); } else { StatDialog->setMinimumSize(300, 400); StatDialog->setMaximumSize(300, 400); } Label1 = new QLabel(StatDialog); Label1->setAlignment(Qt::AlignLeft | Qt::AlignTop); pushButton1 = new QPushButton(StatDialog); pushButton1->setMinimumSize(100, 25); pushButton1->setText("&Close"); hlayout1_1_1 = new QHBoxLayout; hlayout1_1_1->addWidget(pushButton1); hlayout1_1_1->addStretch(100); vlayout1_1 = new QVBoxLayout; vlayout1_1->setSpacing(20); vlayout1_1->addWidget(Label1); vlayout1_1->addStretch(100); vlayout1_1->addLayout(hlayout1_1_1); hlayout1 = new QHBoxLayout; hlayout1->addLayout(vlayout1_1, 1); if(signalcomp->ecg_filter != NULL) { hlayout1->addLayout(vlayout2_1, 100); } StatDialog->setLayout(hlayout1); QObject::connect(pushButton1, SIGNAL(clicked()), StatDialog, SLOT(close())); for(i=0; i<300; i++) { bpm_distribution[i] = 0; } if(signalcomp->ecg_filter == NULL) { if((signalcomp->stat_cnt < 1) || (pagetime < 10LL)) { if(signalcomp->alias[0] != 0) { sprintf(stat_str, "Signal: %s\n\nSamples: 0\n\nSum: 0 %s\n\nMean: 0 %s\n\nRMS: 0 %s\n\nMRS: 0 %s\n\nZero crossings: 0\n\nFrequency: 0 Hz", signalcomp->alias, signalcomp->physdimension, signalcomp->physdimension, signalcomp->physdimension, signalcomp->physdimension); } else { sprintf(stat_str, "Signal: %s\n\nSamples: 0\n\nSum: 0 %s\n\nMean: 0 %s\n\nRMS: 0 %s\n\nMRS: 0 %s\n\nZero crossings: 0\n\nFrequency: 0 Hz", signalcomp->signallabel, signalcomp->physdimension, signalcomp->physdimension, signalcomp->physdimension, signalcomp->physdimension); } } else { if(signalcomp->alias[0] != 0) { sprintf(stat_str, "Signal: %s\n\nSamples: %i\n\nSum: %f %s\n\nMean: %f %s\n\nRMS: %f %s\n\nMRS: %f %s\n\nZero crossings: %i\n\nFrequency: %f Hz", signalcomp->alias, signalcomp->stat_cnt, signalcomp->stat_sum * signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].bitvalue, signalcomp->physdimension, (signalcomp->stat_sum * signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].bitvalue) / signalcomp->stat_cnt, signalcomp->physdimension, sqrt(signalcomp->stat_sum_sqr / signalcomp->stat_cnt) * signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].bitvalue, signalcomp->physdimension, (signalcomp->stat_sum_rectified / signalcomp->stat_cnt) * signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].bitvalue, signalcomp->physdimension, signalcomp->stat_zero_crossing_cnt, (((double)signalcomp->stat_zero_crossing_cnt / 2.0)) / ((double)pagetime / (double)TIME_DIMENSION) ); } else { sprintf(stat_str, "Signal: %s\n\nSamples: %i\n\nSum: %f %s\n\nMean: %f %s\n\nRMS: %f %s\n\nMRS: %f %s\n\nZero crossings: %i\n\nFrequency: %f Hz", signalcomp->signallabel, signalcomp->stat_cnt, signalcomp->stat_sum * signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].bitvalue, signalcomp->physdimension, (signalcomp->stat_sum * signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].bitvalue) / signalcomp->stat_cnt, signalcomp->physdimension, sqrt(signalcomp->stat_sum_sqr / signalcomp->stat_cnt) * signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].bitvalue, signalcomp->physdimension, (signalcomp->stat_sum_rectified / signalcomp->stat_cnt) * signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].bitvalue, signalcomp->physdimension, signalcomp->stat_zero_crossing_cnt, (((double)signalcomp->stat_zero_crossing_cnt / 2.0)) / ((double)pagetime / (double)TIME_DIMENSION) ); } } } else { beat_cnt = ecg_filter_get_beat_cnt(signalcomp->ecg_filter); beat_interval_list = ecg_filter_get_interval_beatlist(signalcomp->ecg_filter); if(beat_cnt < 3) { sprintf(stat_str, "Not enough beats."); } else { average_bpm = 0.0; average_rr = 0.0; sdnn_bpm = 0.0; sdnn_rr = 0.0; rmssd_rr = 0.0; NN50 = 0; buf_bpm = (double *)malloc(sizeof(double) * beat_cnt); if(buf_bpm == NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "The system was not able to provide enough resources (memory) to perform the requested action."); messagewindow.exec(); return; } for(i=0; i 0.05 ) || ((beat_interval_list[i + 1] - beat_interval_list[i]) > 0.05 )) { NN50++; } } } average_bpm /= beat_cnt; average_rr /= beat_cnt; rmssd_rr /= beat_cnt; rmssd_rr = sqrt(rmssd_rr); pNN50 = (NN50 * 100) / (beat_cnt - 1); for(i=0; i 0) && (tmp < 301)) { bpm_distribution[tmp-1]++; } } max_val = 1; for(i=0; i<300; i++) { if(bpm_distribution[i] > max_val) { max_val = bpm_distribution[i]; } } for(i=0; i<300; i++) { if(bpm_distribution[i] > (max_val / 70)) { start_ruler = i; break; } } for(i=299; i>=0; i--) { if(bpm_distribution[i] > (max_val / 70)) { end_ruler = i + 1; if(end_ruler > 300) { end_ruler = 300; } break; } } if(start_ruler >= end_ruler) { start_ruler = 0; end_ruler = 300; } startSlider->setValue(start_ruler); stopSlider->setValue(end_ruler); curve1->setH_RulerValues(start_ruler + 1, end_ruler + 1); curve1->drawCurve(bpm_distribution + start_ruler, end_ruler - start_ruler, (int)(max_val * 1.1) + 1, 0.0); QObject::connect(startSlider, SIGNAL(valueChanged(int)), this, SLOT(startSliderMoved(int))); QObject::connect(stopSlider, SIGNAL(valueChanged(int)), this, SLOT(stopSliderMoved(int))); } } Label1->setText(stat_str); StatDialog->exec(); } void UI_StatisticWindow::startSliderMoved(int) { startSlider->blockSignals(TRUE); stopSlider->blockSignals(TRUE); start_ruler = startSlider->value(); end_ruler = stopSlider->value(); if(end_ruler < (start_ruler + 5)) { end_ruler = start_ruler + 5; stopSlider->setValue(end_ruler); } curve1->setH_RulerValues(start_ruler + 1, end_ruler + 1); curve1->drawCurve(bpm_distribution + start_ruler, end_ruler - start_ruler, (int)(max_val * 1.1) + 1, 0.0); startSlider->blockSignals(FALSE); stopSlider->blockSignals(FALSE); } void UI_StatisticWindow::stopSliderMoved(int) { startSlider->blockSignals(TRUE); stopSlider->blockSignals(TRUE); start_ruler = startSlider->value(); end_ruler = stopSlider->value(); if(start_ruler > (end_ruler - 5)) { start_ruler = end_ruler - 5; startSlider->setValue(start_ruler); } curve1->setH_RulerValues(start_ruler + 1, end_ruler + 1); curve1->drawCurve(bpm_distribution + start_ruler, end_ruler - start_ruler, (int)(max_val * 1.1) + 1, 0.0); startSlider->blockSignals(FALSE); stopSlider->blockSignals(FALSE); } edfbrowser_153_source/PaxHeaders.2978/flywheel.cpp0000644000175000001440000000013212251654530020472 xustar000000000000000030 mtime=1386699096.478032517 30 atime=1386699096.478032517 30 ctime=1386699096.478032517 edfbrowser_153_source/flywheel.cpp0000644000175000001440000001777512251654530020244 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "flywheel.h" UI_Flywheel::UI_Flywheel(QWidget *w_parent) : QWidget(w_parent) { int i; use_move_events = 0; wheel_position = 0.0; spinning = 0; knobs = 10; cursor_above_object = 0; dial_speed = 0; dial_speed_ptr = 0; for(i=0; i<4; i++) { dial_speed_arr[i] = 0; } bordercolor_up = new QColor(224, 224, 224); bordercolor_down = new QColor(92, 92, 92); linearGrad = new QLinearGradient(); // linearGrad->setColorAt(0, QColor(155, 155, 155)); // linearGrad->setColorAt(1, QColor(95, 95, 95)); linearGrad->setColorAt(0, QColor(175, 175, 175)); linearGrad->setColorAt(1, QColor(75, 75, 75)); t1 = new QTimer(this); t2 = new QTimer(this); t2->setSingleShot(TRUE); connect(t1, SIGNAL(timeout()), this, SLOT(wheel_rotate())); connect(t2, SIGNAL(timeout()), this, SLOT(t2_time_out())); } UI_Flywheel::~UI_Flywheel() { delete bordercolor_up; delete bordercolor_down; delete linearGrad; } void UI_Flywheel::t2_time_out(void) { dial_speed = 0; } void UI_Flywheel::wheel_rotate(void) { int h, cumulative_pixels=0; double circum; t2->start(100); h = height(); circum = (M_PI * (double)h); if(use_move_events && (!spinning)) { wheel_position += (((M_PI * 2.0) / (circum / (double)mouse_delta_y)) + (M_PI * 2.0)); while(wheel_position >= (M_PI * 2.0)) { wheel_position -= (M_PI * 2.0); } while(wheel_position < 0.0) { wheel_position += (M_PI * 2.0); } cumulative_pixels = mouse_delta_y; } if(spinning) { if(dial_speed) { wheel_position += ((M_PI * 2.0) / (circum / ((double)dial_speed / 25.0))); cumulative_pixels = (double)dial_speed / 25.0; while(wheel_position >= (M_PI * 2.0)) { wheel_position -= (M_PI * 2.0); } while(wheel_position < 0.0) { wheel_position += (M_PI * 2.0); } if(holdoff) { holdoff--; } else { if(dial_speed > 0) { dial_speed -= 25; if(dial_speed < 0) { dial_speed = 0; } } else { dial_speed += 25; if(dial_speed > 0) { dial_speed = 0; } } if((dial_speed < 500) && (dial_speed > -500)) { if((dial_speed < 125) && (dial_speed > -125)) { holdoff = 6; } else { holdoff = 3; } } } } if(dial_speed == 0) { t1->stop(); spinning = 0; } } update(); emit dialMoved(cumulative_pixels); } void UI_Flywheel::paintEvent(QPaintEvent *) { int w, h, h_2, i, j, b1, b2; double knobstep, rad, rad_offset; QPainter painter(this); w = width(); h = height(); h_2 = h / 2; knobstep = (M_PI * 2.0) / (double)(knobs * 2); linearGrad->setStart(QPoint(w / 2, 0)); linearGrad->setFinalStop(QPoint(w / 2, h)); painter.fillRect(0, 0, w-1, h-1, QBrush(*linearGrad)); rad_offset = wheel_position; while(rad_offset > (knobstep * 2.0)) { rad_offset -= (knobstep * 2.0); } for(i=0; i= M_PI) { b2 = h; } else { b2 = h_2 - (h_2 * cos(rad)); } // j = 222.0 - ((60.0 / (double)h) * (((double)b1 + (double)b2) / 2.0)); j = 240.0 - ((100.0 / (double)h) * (((double)b1 + (double)b2) / 2.0)); painter.fillRect(1, b1, w-2, b2 - b1, QColor(j, j, j)); if(b1 > h_2) { if(b1 > (h * 0.75)) { if(b1 > (h * 0.9)) { painter.fillRect(1, b1, w-2, 3, *bordercolor_up); } else { painter.fillRect(1, b1, w-2, 2, *bordercolor_up); } } painter.setPen(*bordercolor_up); painter.drawLine(1, b1, w-2, b1); } if(b2 < h_2) { if(b2 < (h * 0.25)) { if(b2 < (h * 0.1)) { painter.fillRect(1, b2, w-2, 2, *bordercolor_down); } else { painter.fillRect(1, b2, w-2, 2, *bordercolor_down); } } painter.setPen(*bordercolor_down); painter.drawLine(1, b2, w-2, b2); } } painter.setPen(Qt::black); painter.drawRect(0, 0, w-1, h-1); } void UI_Flywheel::mousePressEvent(QMouseEvent *press_event) { int i; if(press_event->button()==Qt::LeftButton) { for(i=0; i<4; i++) { dial_speed_arr[i] = 0; } spinning = 0; dial_speed = 0; t1->stop(); mouse_old_y = press_event->y(); gettimeofday(&tv, NULL); time_old = tv.tv_usec; time_new = tv.tv_usec; use_move_events = 1; cursor_above_object = 1; setMouseTracking(TRUE); t2->start(100); } } void UI_Flywheel::mouseReleaseEvent(QMouseEvent *release_event) { if(release_event->button()==Qt::LeftButton) { if(use_move_events && (!spinning)) { if((dial_speed > 50) || (dial_speed < -50)) { spinning = 1; holdoff = 0; t1->start(40); } } setMouseTracking(FALSE); use_move_events = 0; cursor_above_object = 0; } } void UI_Flywheel::mouseMoveEvent(QMouseEvent *move_event) { int i, mouse_x; if(use_move_events) { mouse_y = move_event->y(); mouse_x = move_event->x(); mouse_delta_y = mouse_y - mouse_old_y; mouse_old_y = mouse_y; if((mouse_y > height()) || (mouse_y < 0) || (mouse_x > width()) || (mouse_x < 0)) { if((cursor_above_object == 1) && (!spinning)) { if((dial_speed > 50) || (dial_speed < -50)) { spinning = 1; holdoff = 0; t1->start(40); } } cursor_above_object = 0; } else { if(cursor_above_object == 1) { gettimeofday(&tv, NULL); time_old = time_new; time_new = tv.tv_usec; if(time_new > time_old) { dial_speed_arr[dial_speed_ptr] = (mouse_delta_y * 1000000) / (time_new - time_old); } else { dial_speed_arr[dial_speed_ptr] = (mouse_delta_y * 1000000) / (1000000 + time_new - time_old); } dial_speed_ptr++; dial_speed_ptr %= 4; dial_speed = 0; for(i=0; i<4; i++) { dial_speed += dial_speed_arr[i]; } dial_speed /= 4; } spinning = 0; t1->stop(); cursor_above_object = 1; wheel_rotate(); } } } edfbrowser_153_source/PaxHeaders.2978/filtercurve.cpp0000644000175000001440000000013212251654530021205 xustar000000000000000030 mtime=1386699096.477032522 30 atime=1386699096.477032522 30 ctime=1386699096.477032522 edfbrowser_153_source/filtercurve.cpp0000644000175000001440000001706012251654530020742 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "filtercurve.h" FilterCurve::FilterCurve(QWidget *w_parent) : QWidget(w_parent) { setAttribute(Qt::WA_OpaquePaintEvent); SignalColor1 = Qt::blue; SignalColor2 = QColor(210, 210, 0); tracewidth = 0; BackgroundColor = Qt::gray; RasterColor = Qt::darkGray; MarkerColor = Qt::black; h_rastersize = 10; v_rastersize = 10; drawcurve_before_raster = 0; buf1 = NULL; buf2 = NULL; marker_1 = 0; marker_2 = 0; } void FilterCurve::paintEvent(QPaintEvent *) { int i, w, h; double v_sens, offset, h_step, rasterstep; w = width(); h = height(); QPainter painter(this); painter.fillRect(0, 0, w, h, BackgroundColor); if(w < 5) return; if(h < 5) return; /////////////////////////////////// draw the curve /////////////////////////////////////////// if(drawcurve_before_raster) { if(buf1 == NULL) return; if(buf2 != NULL) { if(max_value2 == min_value2) return; if(bufsize2 < 2) return; offset = (-(max_value2)); v_sens = (-(h / (max_value2 - min_value2))); h_step = (double)w / (double)(bufsize2 - 1); painter.setPen(QPen(QBrush(SignalColor2, Qt::SolidPattern), tracewidth, Qt::SolidLine, Qt::SquareCap, Qt::BevelJoin)); for(i = 0; i < (bufsize2 - 1); i++) { painter.drawLine(i * h_step, (buf2[i] + offset) * v_sens, (i + 1) * h_step, (buf2[i + 1] + offset) * v_sens); } } if(max_value1 == min_value1) return; if(bufsize1 < 2) return; offset = (-(max_value1)); v_sens = (-(h / (max_value1 - min_value1))); h_step = (double)w / (double)(bufsize1 - 1); painter.setPen(QPen(QBrush(SignalColor1, Qt::SolidPattern), tracewidth, Qt::SolidLine, Qt::SquareCap, Qt::BevelJoin)); for(i = 0; i < (bufsize1 - 1); i++) { painter.drawLine(i * h_step, (buf1[i] + offset) * v_sens, (i + 1) * h_step, (buf1[i + 1] + offset) * v_sens); } } /////////////////////////////////// draw the rasters /////////////////////////////////////////// painter.setPen(RasterColor); painter.drawRect (0, 0, w - 1, h - 1); if(h_rastersize > 1) { rasterstep = (double)w / h_rastersize; for(i = 1; i < h_rastersize; i++) { painter.drawLine(i * rasterstep, 0, i * rasterstep, h); } } if(v_rastersize > 1) { rasterstep = (double)h / v_rastersize; for(i = 1; i < v_rastersize; i++) { painter.drawLine(0, i * rasterstep, w, i * rasterstep); } } /////////////////////////////////// draw the curve /////////////////////////////////////////// if(!drawcurve_before_raster) { if(buf1 == NULL) return; if(buf2 != NULL) { if(max_value2 == min_value2) return; if(bufsize2 < 2) return; offset = (-(max_value2)); v_sens = (-(h / (max_value2 - min_value2))); h_step = (double)w / (double)(bufsize2 - 1); painter.setPen(QPen(QBrush(SignalColor2, Qt::SolidPattern), tracewidth, Qt::SolidLine, Qt::SquareCap, Qt::BevelJoin)); for(i = 0; i < (bufsize2 - 1); i++) { painter.drawLine(i * h_step, (buf2[i] + offset) * v_sens, (i + 1) * h_step, (buf2[i + 1] + offset) * v_sens); } } if(max_value1 == min_value1) return; if(bufsize1 < 2) return; offset = (-(max_value1)); v_sens = (-(h / (max_value1 - min_value1))); h_step = (double)w / (double)(bufsize1 - 1); painter.setPen(QPen(QBrush(SignalColor1, Qt::SolidPattern), tracewidth, Qt::SolidLine, Qt::SquareCap, Qt::BevelJoin)); for(i = 0; i < (bufsize1 - 1); i++) { painter.drawLine(i * h_step, (buf1[i] + offset) * v_sens, (i + 1) * h_step, (buf1[i + 1] + offset) * v_sens); } } /////////////////////////////////// draw the markers /////////////////////////////////////////// painter.setFont(QFont("Arial", 8)); if((marker_1) || (marker_2)) { painter.drawText(2, 10, "0 Hz"); } if(marker_1) { painter.drawText(2 + marker_1, 10, "F1"); } if(marker_2) { painter.drawText(1 + marker_2, 10, "F2"); } if((marker_1) || (marker_2)) { painter.setPen(SignalColor2); painter.drawText(w - 35, 10, "0 degr."); painter.drawText(w - 45, h - 2, "360 degr."); } if(marker_1) { painter.setPen(QPen(QBrush(MarkerColor, Qt::SolidPattern), 0, Qt::DotLine, Qt::SquareCap, Qt::BevelJoin)); painter.drawLine(marker_1, 0, marker_1, h); } if(marker_2) { painter.setPen(QPen(QBrush(MarkerColor, Qt::SolidPattern), 0, Qt::DotLine, Qt::SquareCap, Qt::BevelJoin)); painter.drawLine(marker_2, 0, marker_2, h); } } void FilterCurve::drawCurve(double *samplebuf, int bsize, double max_val, double min_val) { buf1 = samplebuf; bufsize1 = bsize; max_value1 = max_val; min_value1 = min_val; buf2 = NULL; marker_1 = 0; marker_2 = 0; update(); } void FilterCurve::drawCurve(double *samplebuf, int bsize, double max_val, double min_val, double *samplebuf2, int size2, double max_val2, double min_val2, int mrkr1, int mrkr2) { buf1 = samplebuf; bufsize1 = bsize; max_value1 = max_val; min_value1 = min_val; buf2 = samplebuf2; bufsize2 = size2; max_value2 = max_val2; min_value2 = min_val2; if(mrkr1 > 0) { marker_1 = mrkr1; } else { marker_1 = 0; } if(mrkr2 > 0) { marker_2 = mrkr2; } else { marker_2 = 0; } update(); } void FilterCurve::setSignalColor1(QColor newColor) { SignalColor1 = newColor; update(); } void FilterCurve::setSignalColor2(QColor newColor) { SignalColor2 = newColor; update(); } void FilterCurve::setTraceWidth(int tr_width) { tracewidth = tr_width; if(tracewidth < 0) tracewidth = 0; update(); } void FilterCurve::setBackgroundColor(QColor newColor) { BackgroundColor = newColor; update(); } void FilterCurve::setRasterColor(QColor newColor) { RasterColor = newColor; update(); } void FilterCurve::setMarkerColor(QColor newColor) { MarkerColor = newColor; update(); } void FilterCurve::setH_RasterSize(int newsize) { h_rastersize = newsize; update(); } void FilterCurve::setV_RasterSize(int newsize) { v_rastersize = newsize; update(); } edfbrowser_153_source/PaxHeaders.2978/xml.h0000644000175000001440000000013212251654530017120 xustar000000000000000030 mtime=1386699096.468032569 30 atime=1386699096.468032569 30 ctime=1386699096.468032569 edfbrowser_153_source/xml.h0000644000175000001440000000474212251654530016660 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef xml_INCLUDED #define xml_INCLUDED #include #include #include struct xml_handle { FILE *file; int level; int offset; int len; char *elementname; char *attributes; struct xml_handle *parent_handle_p; struct xml_handle *child_handle_p; char *tag_search_result; int encoding; }; struct xml_handle * xml_get_handle(const char *); struct xml_handle * xml_create_handle(const char *, char *); void xml_close(struct xml_handle *); void xml_go_up(struct xml_handle *); int xml_goto_nth_element_inside(struct xml_handle *, const char *, int); int xml_goto_next_element_with_same_name(struct xml_handle *); int xml_goto_next_element_at_same_level(struct xml_handle *); void xml_goto_root(struct xml_handle *); char * xml_get_content_of_element(struct xml_handle *); void xml_strcpy_encode_entity(char *, const char *); int xml_strncpy_encode_entity(char *, const char *, int); void xml_fwrite_encode_entity(FILE *, const char *); void xml_fnwrite_encode_entity(FILE *, const char *, int); void xml_strcpy_decode_entity(char *, const char *); int xml_strncpy_decode_entity(char *, const char *, int); int xml_character_encoding_type(struct xml_handle *); int xml_get_attribute_of_element(struct xml_handle *, const char *, char *, int); #endif edfbrowser_153_source/PaxHeaders.2978/unisens2edf.cpp0000644000175000001440000000013212251654530021100 xustar000000000000000030 mtime=1386699096.479032511 30 atime=1386699096.479032511 30 ctime=1386699096.479032511 edfbrowser_153_source/unisens2edf.cpp0000644000175000001440000017131712251654530020643 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "unisens2edf.h" #if defined(__APPLE__) || defined(__MACH__) || defined(__APPLE_CC__) #define fopeno fopen #else #define fseeko fseeko64 #define ftello ftello64 #define fopeno fopen64 #endif #define US_DATATYPE_FLOAT_LI 0 #define US_DATATYPE_FLOAT_BI 1 #define US_DATATYPE_DOUBLE_LI 2 #define US_DATATYPE_DOUBLE_BI 3 #define US_DATATYPE_INT64_LI 4 #define US_DATATYPE_INT64_BI 5 #define US_DATATYPE_UINT64_LI 6 #define US_DATATYPE_UINT64_BI 7 #define US_DATATYPE_INT32_LI 8 #define US_DATATYPE_INT32_BI 9 #define US_DATATYPE_UINT32_LI 10 #define US_DATATYPE_UINT32_BI 11 #define US_DATATYPE_INT24_LI 12 #define US_DATATYPE_INT24_BI 13 #define US_DATATYPE_UINT24_LI 14 #define US_DATATYPE_UINT24_BI 15 #define US_DATATYPE_INT16_LI 16 #define US_DATATYPE_INT16_BI 17 #define US_DATATYPE_UINT16_LI 18 #define US_DATATYPE_UINT16_BI 19 #define US_DATATYPE_INT8_LI 20 #define US_DATATYPE_INT8_BI 21 #define US_DATATYPE_UINT8_LI 22 #define US_DATATYPE_UINT8_BI 23 #define US_SAMPLERATE_OUT_OF_RANGE 22 UI_UNISENS2EDFwindow::UI_UNISENS2EDFwindow(char *recent_dir, char *save_dir) { char txt_string[2048]; recent_opendir = recent_dir; recent_savedir = save_dir; myobjectDialog = new QDialog; myobjectDialog->setMinimumSize(QSize(600, 480)); myobjectDialog->setMaximumSize(QSize(600, 480)); myobjectDialog->setWindowTitle("Unisens to EDF+ converter"); myobjectDialog->setModal(TRUE); myobjectDialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); pushButton1 = new QPushButton(myobjectDialog); pushButton1->setGeometry(QRect(20, 430, 100, 26)); pushButton1->setText("Select File"); pushButton2 = new QPushButton(myobjectDialog); pushButton2->setGeometry(QRect(480, 430, 100, 26)); pushButton2->setText("Close"); textEdit1 = new QTextEdit(myobjectDialog); textEdit1->setGeometry(QRect(20, 20, 560, 380)); textEdit1->setFrameStyle(QFrame::Panel | QFrame::Sunken); textEdit1->setReadOnly(TRUE); textEdit1->setLineWrapMode(QTextEdit::NoWrap); sprintf(txt_string, "Unisens to EDF+ converter.\n"); textEdit1->append(txt_string); QObject::connect(pushButton1, SIGNAL(clicked()), this, SLOT(SelectFileButton())); QObject::connect(pushButton2, SIGNAL(clicked()), myobjectDialog, SLOT(close())); myobjectDialog->exec(); } void UI_UNISENS2EDFwindow::SelectFileButton() { int i, j, k, n, tmp, chns, hdl, err, *buf2, bufsize, blocks_written, progress_steps, lines; short tmp3; char path[MAX_PATH_LENGTH], binfilepath[MAX_PATH_LENGTH], outputfilename[MAX_PATH_LENGTH], scratchpad[2048], str[256], *buf1, tmp2, linebuf[512]; struct xml_handle *xml_hdl; strcpy(path, QFileDialog::getOpenFileName(0, "Select inputfile", QString::fromLocal8Bit(recent_opendir), "XML files (*.xml *.XML)").toLocal8Bit().data()); if(!strcmp(path, "")) { return; } get_directory_from_path(recent_opendir, path, MAX_PATH_LENGTH); xml_hdl = xml_get_handle(path); if(xml_hdl == NULL) { sprintf(scratchpad, "Error, can not open file:\n%s\n", path); textEdit1->append(QString::fromLocal8Bit(scratchpad)); return; } sprintf(scratchpad, "Processing file:\n%s", path); textEdit1->append(QString::fromLocal8Bit(scratchpad)); char_encoding = xml_hdl->encoding; if(char_encoding == 0) // attribute encoding not present { char_encoding = 2; // fallback to UTF-8 because it is the default for XML } else if(char_encoding > 2) // unknown encoding FIX ME!! { char_encoding = 1; // fallback to ISO-8859-1 (Latin1) } if(strcmp(xml_hdl->elementname, "unisens")) { textEdit1->append("Error, can not find root element \"unisens\".\n"); xml_close(xml_hdl); return; } if(xml_get_attribute_of_element(xml_hdl, "timestampStart", str, 255)) { textEdit1->append("Error, can not find attribute \"timestampStart\".\n"); return; } if((strlen(str) < 19) || (strlen(str) > 23) || (str[4] != '-') || (str[7] != '-') || (str[10] != 'T') || (str[13] != ':') || (str[16] != ':')) { textEdit1->append("Error, can not find attribute \"timestampStart\".\n"); return; } err = 0; for(i=0; i<19; i++) { if((i == 4) || (i == 7) || (i == 10) || (i == 13) || (i == 16)) continue; if(!(isdigit(str[i]))) err = 1; } if(strlen(str) == 23) { if(str[19] != '.') err = 1; for(i=20; i<23; i++) { if(!(isdigit(str[i]))) err = 1; } starttime_fraction = atoi(str + 20); if((starttime_fraction < 0) || (starttime_fraction > 999)) err = 1; } else { starttime_fraction = 0; } if(err) { textEdit1->append("Error, invalid format in attribute \"timestampStart\".\n"); return; } strncpy(str_timestampStart, str, 19); str_timestampStart[19] = 0; if(xml_get_attribute_of_element(xml_hdl, "measurementId", str, 255)) { textEdit1->append("Error, can not find attribute \"measurementId\".\n"); return; } if(strlen(str) < 1) { textEdit1->append("Error, attribute \"measurementId\" has no data.\n"); return; } if(char_encoding == 1) // Latin-1 { strncpy(str_measurementId, QString::fromLatin1(str).toLocal8Bit().data(), 128); } else if(char_encoding == 2) { strncpy(str_measurementId, QString::fromUtf8(str).toLocal8Bit().data(), 128); } else { // strncpy(str_measurementId, str, 128); strncpy(str_measurementId, QString::fromUtf8(str).toLocal8Bit().data(), 128); // default for XML is UTF-8 } str_measurementId[127] = 0; xml_goto_root(xml_hdl); ////////////////////////// read parameters from XML-file ////////////////////////////////////////// total_edf_signals = 0; bdf = 0; int skip = 0; sf_less_1 = 0; for(file_cnt=0; file_cntappend("Error, can not find element \"csvFileFormat\".\n"); xml_close(xml_hdl); for(i=0; iappend("Error, can not find attribute \"separator\".\n"); xml_close(xml_hdl); for(i=0; iappend("Error, value for \"separator\" must be one character.\n"); xml_close(xml_hdl); for(i=0; iappend("Error, value for \"decimalSeparator\" must be one character.\n"); xml_close(xml_hdl); for(i=0; iappend("Error, attribute \"decimalSeparator\" and \"separator\" have equal values.\n"); xml_close(xml_hdl); for(i=0; iappend("Error, can not find element \"binFileFormat\".\n"); xml_close(xml_hdl); for(i=0; iappend("Error, can not find attribute \"endianess\".\n"); xml_close(xml_hdl); for(i=0; iappend("Error, can not find attribute \"endianess\".\n"); xml_close(xml_hdl); for(i=0; iappend("Error, attribute \"endianess\" has an unknown value.\n"); xml_close(xml_hdl); for(i=0; iappend("Error, can not find attribute \"name\" in element \"channel\".\n"); xml_close(xml_hdl); for(i=0; iappend("Error, no signals in element \"signalEntry\" or in element \"csvFileFormat\".\n"); xml_close(xml_hdl); for(i=0; i= MAXSIGNALS) { textEdit1->append("Error, too many signals.\n"); xml_close(xml_hdl); for(i=0; iappend(QString::fromLocal8Bit(scratchpad)); xml_close(xml_hdl); for(i=0; iappend("Error, can not find element \"csvFileFormat\".\n"); xml_close(xml_hdl); for(i=0; iappend("Error, can not find attribute \"separator\".\n"); xml_close(xml_hdl); for(i=0; iappend("Error, value for \"separator\" must be one character.\n"); xml_close(xml_hdl); for(i=0; iappend("Error, value for \"decimalSeparator\" must be one character.\n"); xml_close(xml_hdl); for(i=0; iappend("Error, attribute \"decimalSeparator\" and \"separator\" have equal values.\n"); xml_close(xml_hdl); for(i=0; iappend("Error, can not find attribute \"name\" in element \"channel\".\n"); xml_close(xml_hdl); for(i=0; iappend("Error, no signals in element \"valuesEntry\".\n"); xml_close(xml_hdl); for(i=0; i= MAXSIGNALS) { textEdit1->append("Error, too many signals.\n"); xml_close(xml_hdl); for(i=0; iappend(QString::fromLocal8Bit(scratchpad)); xml_close(xml_hdl); for(i=0; iappend("Error, can not find element \"signalEntry\" or element \"csvFileFormat\".\n"); xml_close(xml_hdl); return; } if(total_edf_signals > (MAXSIGNALS - 1)) { textEdit1->append("Error, too many signals (limit is 511).\n"); for(i=0; i max_datablocks) { max_datablocks = datablocks[k]; } } ////////////////////////////////////// Check for and count the triggers //////////////////////////////////////////////////////////// total_annotations = 0; xml_goto_root(xml_hdl); trig_file_cnt = 0; for(k=0; kappend("Error, can not find attribute \"separator\".\n"); xml_close(xml_hdl); for(i=0; iappend("Error, value for \"separator\" must be one character.\n"); xml_close(xml_hdl); for(i=0; iappend("Error, value for \"decimalSeparator\" must be one character.\n"); xml_close(xml_hdl); for(i=0; iappend("Error, attribute \"decimalSeparator\" and \"separator\" have equal values.\n"); xml_close(xml_hdl); for(i=0; iappend(QString::fromLocal8Bit(scratchpad)); for(i=0; i max_datablocks) { tmp = (total_annotations / max_datablocks) + 1; if(tmp > 64) tmp = 64; if(edf_set_number_of_annotation_signals(hdl, tmp)) err = 1; } if(err) { textEdit1->append("An error occurred during initializing the EDF-header.\n"); for(i=0; iappend("Malloc error (buf1)\n"); for(i=0; iappend("Malloc error (buf2)\n"); for(i=0; iprocessEvents(); if(progress.wasCanceled() == TRUE) { break; } } for(k=0; kappend("A read error occurred during the conversion.\n"); for(i=0; iappend("A read error occurred during the conversion.\n"); for(i=0; i> 8) | (((unsigned short)tmp3 & 0x00FF) << 8))) - adcz; } } } else if(datatype[k] == US_DATATYPE_UINT16_BI) { for(i=0; i> 8) | (((unsigned short)tmp3 & 0x00FF) << 8))) - adcz; } } } else if(datatype[k] == US_DATATYPE_INT24_BI) { for(i=0; i> 24) | (((unsigned int)tmp & 0x00FF0000) >> 8) | (((unsigned int)tmp & 0x0000FF00) << 8) | (((unsigned int)tmp & 0x000000FF) << 24))) - adcz; } } } else if(datatype[k] == US_DATATYPE_UINT32_BI) { for(i=0; i> 24) | (((unsigned int)tmp & 0x00FF0000) >> 8) | (((unsigned int)tmp & 0x0000FF00) << 8) | (((unsigned int)tmp & 0x000000FF) << 24))) - adcz; } } } else if(datatype[k] == US_DATATYPE_FLOAT_LI) { for(i=0; i> 24) | (((unsigned int)tmp & 0x00FF0000) >> 8) | (((unsigned int)tmp & 0x0000FF00) << 8) | (((unsigned int)tmp & 0x000000FF) << 24)); buf2_t[(j * sf_t) + i] = var.flp - adcz; } } } } } } else if(blocks_written == datablocks[k]) { if(!nedval_enc[k]) { for(i=0; iappend("A write error occurred.\n"); for(i=0; iappend("Done\n"); } int UI_UNISENS2EDFwindow::get_events_from_csv_files(int max_files, int edf_hdl, const char *path) { int i, k, len, len2, progress_steps, triggers_written=0; char scratchpad[2048], csvfilepath[MAX_PATH_LENGTH], linebuf[1024], *ptr, sep, annotation[64]; long long onset; FILE *csvfile; QProgressDialog progress("Converting triggers ...", "Cancel", 0, total_annotations, myobjectDialog); progress.setWindowModality(Qt::WindowModal); progress.setMinimumDuration(200); progress_steps = total_annotations / 100; if(progress_steps < 1) { progress_steps = 1; } for(k=0; kappend(QString::fromLocal8Bit(scratchpad)); return(1); } sep = csv_sep[k]; while(1) { if(!(triggers_written % progress_steps)) { progress.setValue(triggers_written); qApp->processEvents(); if(progress.wasCanceled() == TRUE) { fclose(csvfile); return(1); } } ptr = fgets(linebuf, 1024, csvfile); if(ptr == NULL) break; len = strlen(linebuf); if(len < 3) continue; for(i=0; i 0)) { *ptr = 0; onset = atoi(linebuf); strncpy(annotation, ++ptr, 46); annotation[45] = 0; len2 = strlen(annotation); if(annotation[len2 - 1] == '\n') { annotation[--len2] = 0; } if(annotation[len2 - 1] == '\r') { annotation[--len2] = 0; } if(annotation[len2 - 1] == sep) { annotation[--len2] = 0; } remove_leading_spaces(annotation); remove_trailing_spaces(annotation); onset *= 10000LL; onset /= evt_sf[k]; if(char_encoding == 1) { if(edfwrite_annotation_latin1(edf_hdl, onset, -1LL, annotation)) { progress.reset(); textEdit1->append("An error occurred while writing the events to the EDF-file.\n"); return(1); } } if(char_encoding == 2) { if(edfwrite_annotation_utf8(edf_hdl, onset, -1LL, annotation)) { progress.reset(); textEdit1->append("An error occurred while writing the events to the EDF-file.\n"); return(1); } } triggers_written++; break; } else { break; } } ptr++; } } fclose(csvfile); } progress.reset(); return(0); } int UI_UNISENS2EDFwindow::count_events_from_csv_files(int max_files, const char *path, int *result) { int evt_cnt=0, k; char scratchpad[2048], csvfilepath[MAX_PATH_LENGTH], linebuf[1024], *ptr; FILE *csvfile; *result = 0; for(k=0; kappend(QString::fromLocal8Bit(scratchpad)); return(1); } while(1) { ptr = fgets(linebuf, 1024, csvfile); if(ptr == NULL) break; evt_cnt++; } fclose(csvfile); } *result = evt_cnt; return(0); } int UI_UNISENS2EDFwindow::get_signalparameters_from_BIN_attributes(struct xml_handle *xml_hdl, int file_nr) { char str[256], scratchpad[2048]; double d_tmp; if(xml_get_attribute_of_element(xml_hdl, "id", str, 255)) { textEdit1->append("Error, can not find attribute \"id\".\n"); return(1); } if(strlen(str) < 1) { textEdit1->append("Error, attribute \"id\" has no value.\n"); return(1); } strncpy(binfilename[file_nr], str, MAX_PATH_LENGTH - 1); if(xml_get_attribute_of_element(xml_hdl, "adcResolution", str, 255)) { adcres[file_nr] = 0; } else if(strlen(str) < 1) { adcres[file_nr] = 0; } else adcres[file_nr] = atoi(str); if(xml_get_attribute_of_element(xml_hdl, "unit", str, 255)) { strcpy(physdim[file_nr], "X"); } else if(strlen(str) < 1) { strcpy(physdim[file_nr], "X"); } else if(char_encoding == 1) // Latin-1 { strncpy(physdim[file_nr], str, 8); } else if(char_encoding == 2) { strncpy(physdim[file_nr], QString::fromUtf8(str).toLatin1().data(), 8); } else { // strncpy(physdim[file_nr], str, 8); strncpy(physdim[file_nr], QString::fromUtf8(str).toLatin1().data(), 8); // default for XML is UTF-8 } physdim[file_nr][8] = 0; remove_leading_spaces(physdim[file_nr]); remove_trailing_spaces(physdim[file_nr]); if(xml_get_attribute_of_element(xml_hdl, "sampleRate", str, 255)) { textEdit1->append("Error, can not find attribute \"sampleRate\".\n"); return(1); } if(strlen(str) < 1) { textEdit1->append("Error, attribute \"sampleRate\" has no value."); return(1); } sf_inv[file_nr] = 0; sf[file_nr] = nearbyint(atof(str)); if((sf[file_nr] < 1) || (sf[file_nr] > 1000000)) { if(sf[file_nr] < 1) { d_tmp = atof(str); if(d_tmp >= 0.001) { sf_inv[file_nr] = nearbyint(1.0 / d_tmp); sf[file_nr] = 1; sf_less_1 = 1; } else { return(US_SAMPLERATE_OUT_OF_RANGE); } } else { return(US_SAMPLERATE_OUT_OF_RANGE); } } if(!xml_get_attribute_of_element(xml_hdl, "baseline", str, 255)) { if(strlen(str) < 1) { textEdit1->append("Error, attribute \"baseline\" has no value.\n"); return(1); } baseline[file_nr] = atoll(str); } else { baseline[file_nr] = 0LL; } if(!xml_get_attribute_of_element(xml_hdl, "adcZero", str, 255)) { if(strlen(str) < 1) { textEdit1->append("Error, attribute \"adcZero\" has no value.\n"); return(1); } adczero[file_nr] = atoll(str); } else { adczero[file_nr] = 0LL; } if(xml_get_attribute_of_element(xml_hdl, "lsbValue", str, 255)) { lsbval[file_nr] = 1.0; } else if(strlen(str) < 1) { lsbval[file_nr] = 1.0; } else lsbval[file_nr] = atof(str); if((lsbval[file_nr] < -1000000.0) || (lsbval[file_nr] > 1000000.0)) { textEdit1->append("Error, attribute \"lsbValue\" is out of range.\n"); return(1); } physmax[file_nr] = lsbval[file_nr]; physmin[file_nr] = lsbval[file_nr]; if(xml_get_attribute_of_element(xml_hdl, "dataType", str, 255)) { textEdit1->append("Error, can not find attribute \"dataType\".\n"); return(1); } if(csv_enc[file_nr]) { if(!strcmp(str, "double")) { datatype[file_nr] = US_DATATYPE_DOUBLE_LI; bdf = 1; straightbinary[file_nr] = 0; samplesize[file_nr] = 8; physmax[file_nr] *= (8388607LL - (baseline[file_nr] - adczero[file_nr])); physmin[file_nr] *= (-8388608LL - (baseline[file_nr] - adczero[file_nr])); digmax[file_nr] = 8388607; digmin[file_nr] = -8388608; } else if(!strcmp(str, "float")) { datatype[file_nr] = US_DATATYPE_FLOAT_LI; bdf = 1; straightbinary[file_nr] = 0; samplesize[file_nr] = 4; physmax[file_nr] *= (8388607LL - (baseline[file_nr] - adczero[file_nr])); physmin[file_nr] *= (-8388608LL - (baseline[file_nr] - adczero[file_nr])); digmax[file_nr] = 8388607; digmin[file_nr] = -8388608; } else if(!strcmp(str, "int32")) { datatype[file_nr] = US_DATATYPE_INT32_LI; bdf = 1; straightbinary[file_nr] = 0; samplesize[file_nr] = 4; physmax[file_nr] *= (8388607LL - (baseline[file_nr] - adczero[file_nr])); physmin[file_nr] *= (-8388608LL - (baseline[file_nr] - adczero[file_nr])); digmax[file_nr] = 8388607; digmin[file_nr] = -8388608; } else if(!strcmp(str, "uint32")) { datatype[file_nr] = US_DATATYPE_UINT32_LI; bdf = 1; straightbinary[file_nr] = 1; samplesize[file_nr] = 4; physmax[file_nr] *= (8388607LL - (baseline[file_nr] - adczero[file_nr])); physmin[file_nr] *= (-8388608LL - (baseline[file_nr] - adczero[file_nr])); digmax[file_nr] = 8388607; digmin[file_nr] = -8388608; } else if(!strcmp(str, "int16")) { datatype[file_nr] = US_DATATYPE_INT16_LI; straightbinary[file_nr] = 0; samplesize[file_nr] = 2; physmax[file_nr] *= (32767LL - (baseline[file_nr] - adczero[file_nr])); physmin[file_nr] *= (-32768LL - (baseline[file_nr] - adczero[file_nr])); digmax[file_nr] = 32767; digmin[file_nr] = -32768; } else if(!strcmp(str, "uint16")) { datatype[file_nr] = US_DATATYPE_UINT16_LI; straightbinary[file_nr] = 1; samplesize[file_nr] = 2; physmax[file_nr] *= (32767LL - (baseline[file_nr] - adczero[file_nr])); physmin[file_nr] *= (-32768LL - (baseline[file_nr] - adczero[file_nr])); digmax[file_nr] = 32767; digmin[file_nr] = -32768; } else if(!strcmp(str, "int8")) { datatype[file_nr] = US_DATATYPE_INT8_LI; straightbinary[file_nr] = 0; samplesize[file_nr] = 1; physmax[file_nr] *= (127 - (baseline[file_nr] - adczero[file_nr])); physmin[file_nr] *= (-128 - (baseline[file_nr] - adczero[file_nr])); digmax[file_nr] = 127; digmin[file_nr] = -128; } else if(!strcmp(str, "uint8")) { datatype[file_nr] = US_DATATYPE_UINT8_LI; straightbinary[file_nr] = 1; samplesize[file_nr] = 1; physmax[file_nr] *= (127 - (baseline[file_nr] - adczero[file_nr])); physmin[file_nr] *= (-128 - (baseline[file_nr] - adczero[file_nr])); digmax[file_nr] = 127; digmin[file_nr] = -128; } else { snprintf(scratchpad, 2047, "Error, unsupported combination of datatype: %s and csv file\n", str); textEdit1->append(scratchpad); return(1); } } else { if(!strcmp(str, "uint8")) { datatype[file_nr] = US_DATATYPE_UINT8_LI; straightbinary[file_nr] = 1; samplesize[file_nr] = 1; physmax[file_nr] *= (127 - (baseline[file_nr] - adczero[file_nr])); physmin[file_nr] *= (-128 - (baseline[file_nr] - adczero[file_nr])); digmax[file_nr] = 127; digmin[file_nr] = -128; } else if(!strcmp(str, "int8")) { datatype[file_nr] = US_DATATYPE_INT8_LI; straightbinary[file_nr] = 0; samplesize[file_nr] = 1; physmax[file_nr] *= (127 - (baseline[file_nr] - adczero[file_nr])); physmin[file_nr] *= (-128 - (baseline[file_nr] - adczero[file_nr])); digmax[file_nr] = 127; digmin[file_nr] = -128; } else if(!strcmp(str, "uint16")) { datatype[file_nr] = US_DATATYPE_UINT16_LI; straightbinary[file_nr] = 1; samplesize[file_nr] = 2; physmax[file_nr] *= (32767LL - (baseline[file_nr] - adczero[file_nr])); physmin[file_nr] *= (-32768LL - (baseline[file_nr] - adczero[file_nr])); digmax[file_nr] = 32767; digmin[file_nr] = -32768; } else if(!strcmp(str, "int16")) { datatype[file_nr] = US_DATATYPE_INT16_LI; straightbinary[file_nr] = 0; samplesize[file_nr] = 2; physmax[file_nr] *= (32767LL - (baseline[file_nr] - adczero[file_nr])); physmin[file_nr] *= (-32768LL - (baseline[file_nr] - adczero[file_nr])); digmax[file_nr] = 32767; digmin[file_nr] = -32768; } else if(!strcmp(str, "uint24")) { datatype[file_nr] = US_DATATYPE_UINT24_LI; bdf = 1; straightbinary[file_nr] = 1; samplesize[file_nr] = 3; physmax[file_nr] *= (8388607LL - (baseline[file_nr] - adczero[file_nr])); physmin[file_nr] *= (-8388608LL - (baseline[file_nr] - adczero[file_nr])); digmax[file_nr] = 8388607; digmin[file_nr] = -8388608; } else if(!strcmp(str, "int24")) { datatype[file_nr] = US_DATATYPE_INT24_LI; bdf = 1; straightbinary[file_nr] = 0; samplesize[file_nr] = 3; physmax[file_nr] *= (8388607LL - (baseline[file_nr] - adczero[file_nr])); physmin[file_nr] *= (-8388608LL - (baseline[file_nr] - adczero[file_nr])); digmax[file_nr] = 8388607; digmin[file_nr] = -8388608; } else if(!strcmp(str, "uint32")) { datatype[file_nr] = US_DATATYPE_UINT32_LI; bdf = 1; straightbinary[file_nr] = 1; samplesize[file_nr] = 4; physmax[file_nr] *= (8388607LL - (baseline[file_nr] - adczero[file_nr])); physmin[file_nr] *= (-8388608LL - (baseline[file_nr] - adczero[file_nr])); digmax[file_nr] = 8388607; digmin[file_nr] = -8388608; } else if(!strcmp(str, "int32")) { datatype[file_nr] = US_DATATYPE_INT32_LI; bdf = 1; straightbinary[file_nr] = 0; samplesize[file_nr] = 4; physmax[file_nr] *= (8388607LL - (baseline[file_nr] - adczero[file_nr])); physmin[file_nr] *= (-8388608LL - (baseline[file_nr] - adczero[file_nr])); digmax[file_nr] = 8388607; digmin[file_nr] = -8388608; } else if(!strcmp(str, "float")) { datatype[file_nr] = US_DATATYPE_FLOAT_LI; bdf = 1; straightbinary[file_nr] = 0; samplesize[file_nr] = 4; physmax[file_nr] *= (8388607LL - (baseline[file_nr] - adczero[file_nr])); physmin[file_nr] *= (-8388608LL - (baseline[file_nr] - adczero[file_nr])); digmax[file_nr] = 8388607; digmin[file_nr] = -8388608; } else { snprintf(scratchpad, 2047, "Error, unsupported combination of datatype: %s and binary file\n", str); textEdit1->append(scratchpad); return(1); } } return(0); } int UI_UNISENS2EDFwindow::get_signalparameters_from_EVT_attributes(struct xml_handle *xml_hdl, int file_nr) { char str[256]; if(xml_get_attribute_of_element(xml_hdl, "id", str, 255)) { textEdit1->append("Error, can not find attribute \"id\".\n"); return(1); } if(strlen(str) < 1) { textEdit1->append("Error, attribute \"id\" has no value.\n"); return(1); } strncpy(evtfilename[file_nr], str, MAX_PATH_LENGTH - 1); if(xml_get_attribute_of_element(xml_hdl, "sampleRate", str, 255)) { textEdit1->append("Error, can not find attribute \"sampleRate\".\n"); return(1); } if(strlen(str) < 1) { textEdit1->append("Error, attribute \"sampleRate\" has no value.\n"); return(1); } evt_sf[file_nr] = atoi(str); if((evt_sf[file_nr] < 1) || (evt_sf[file_nr] > 1000000)) { textEdit1->append("Error, attribute \"sampleRate\" is out of range.\n"); return(1); } return(0); } edfbrowser_153_source/PaxHeaders.2978/main.cpp0000644000175000001440000000013212251654530017577 xustar000000000000000030 mtime=1386699096.478032517 30 atime=1386699096.478032517 30 ctime=1386699096.478032517 edfbrowser_153_source/main.cpp0000644000175000001440000000103012251654530017322 0ustar00novarausers00000000000000 #include #include #include #include #include #include "mainwindow.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); QPixmap pixmap(":/images/splash.png"); QSplashScreen splash(pixmap, Qt::WindowStaysOnTopHint); QTimer t1; t1.setSingleShot(TRUE); QObject::connect(&t1, SIGNAL(timeout()), &splash, SLOT(close())); splash.show(); t1.start(3000); qApp->processEvents(); class UI_Mainwindow MainWindow; return app.exec(); } edfbrowser_153_source/PaxHeaders.2978/edfplusd_cnv.h0000644000175000001440000000013212251654530020774 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/edfplusd_cnv.h0000644000175000001440000000413712251654530020532 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef UI_EDFD2EDFCFORM_H #define UI_EDFD2EDFCFORM_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "check_edf_file.h" #include "edf_annotations.h" #include "utils.h" class UI_EDFDwindow : public QObject { Q_OBJECT public: UI_EDFDwindow(char *, char *); private: QPushButton *pushButton1, *pushButton2; QTextEdit *textEdit1; QDialog *myobjectDialog; char *recent_opendir, *recent_savedir; long long get_datarecord_timestamp(char *); void write_values_to_hdr(FILE *, long long, int, struct edfhdrblock *); void free_annotations(struct annotationblock *); private slots: void SelectFileButton(); }; #endif edfbrowser_153_source/PaxHeaders.2978/edfplusd_cnv.cpp0000644000175000001440000000013212251654530021327 xustar000000000000000030 mtime=1386699096.477032522 30 atime=1386699096.477032522 30 ctime=1386699096.477032522 edfbrowser_153_source/edfplusd_cnv.cpp0000644000175000001440000004463012251654530021067 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "edfplusd_cnv.h" #if defined(__APPLE__) || defined(__MACH__) || defined(__APPLE_CC__) #define fopeno fopen #else #define fseeko fseeko64 #define ftello ftello64 #define fopeno fopen64 #endif UI_EDFDwindow::UI_EDFDwindow(char *recent_ope_dir, char *recent_sav_dir) { char txt_string[2048]; recent_opendir = recent_ope_dir; recent_savedir = recent_sav_dir; myobjectDialog = new QDialog; myobjectDialog->setMinimumSize(QSize(600, 480)); myobjectDialog->setMaximumSize(QSize(600, 480)); myobjectDialog->setWindowTitle("EDF+D/BDF+D to EDF+C/BDF+C converter"); myobjectDialog->setModal(TRUE); myobjectDialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); pushButton1 = new QPushButton(myobjectDialog); pushButton1->setGeometry(QRect(20, 430, 100, 26)); pushButton1->setText("Select File"); pushButton2 = new QPushButton(myobjectDialog); pushButton2->setGeometry(QRect(480, 430, 100, 26)); pushButton2->setText("Close"); textEdit1 = new QTextEdit(myobjectDialog); textEdit1->setGeometry(QRect(20, 20, 560, 380)); textEdit1->setFrameStyle(QFrame::Panel | QFrame::Sunken); textEdit1->setReadOnly(TRUE); textEdit1->setLineWrapMode(QTextEdit::NoWrap); sprintf(txt_string, "EDF+D/BDF+D to EDF+C/BDF+C converter.\n"); textEdit1->append(txt_string); QObject::connect(pushButton1, SIGNAL(clicked()), this, SLOT(SelectFileButton())); QObject::connect(pushButton2, SIGNAL(clicked()), myobjectDialog, SLOT(close())); myobjectDialog->exec(); } void UI_EDFDwindow::SelectFileButton() { FILE *inputfile=NULL, *outputfile=NULL; int i, file_number, offset, offset_2, datarecords, datarecords_read, datarecords_written, cnt, annot_signal_size, annot_signal_size_2, annot_signal_nr, annot_signal_nr_2, annots_written, len, progress_steps; long long former_timestamp, next_timestamp, new_hdr_timestamp, chunk_starttime, chunk_endtime; char txt_string[2048], inputpath[MAX_PATH_LENGTH], output_path[MAX_PATH_LENGTH], *fileheader, *readbuf, *tal; struct annotationblock *annotationlist[1], *annotblock; struct edfhdrblock *edfhdr=NULL; pushButton1->setEnabled(FALSE); strcpy(inputpath, QFileDialog::getOpenFileName(0, "Select inputfile", QString::fromLocal8Bit(recent_opendir), "EDF/BDF files (*.edf *.EDF *.bdf *.BDF *.rec *.REC)").toLocal8Bit().data()); if(!strcmp(inputpath, "")) { pushButton1->setEnabled(TRUE); return; } get_directory_from_path(recent_opendir, inputpath, MAX_PATH_LENGTH); inputfile = fopeno(inputpath, "rb"); if(inputfile==NULL) { snprintf(txt_string, 2048, "Error, can not open file %s for reading.\n", inputpath); textEdit1->append(QString::fromLocal8Bit(txt_string)); pushButton1->setEnabled(TRUE); return; } snprintf(txt_string, 2048, "Processing file %s", inputpath); textEdit1->append(txt_string); /***************** check if the file is valid ******************************/ EDFfileCheck EDFfilechecker; edfhdr = EDFfilechecker.check_edf_file(inputfile, txt_string); if(edfhdr==NULL) { fclose(inputfile); textEdit1->append("Error, file is not a valid EDF or BDF file.\n"); pushButton1->setEnabled(TRUE); return; } if(((!edfhdr->edfplus)&&(!edfhdr->bdfplus))||(!edfhdr->discontinuous)) { free(edfhdr->edfparam); free(edfhdr); fclose(inputfile); textEdit1->append("Error, file is not an EDF+D or BDF+D file.\n"); pushButton1->setEnabled(TRUE); return; } /****************** get annotations ******************************/ edfhdr->file_hdl = inputfile; EDF_annotations annotations_func; annotationlist[0] = NULL; if(annotations_func.get_annotations(0, edfhdr, &annotationlist[0], 0)) { free_annotations(annotationlist[0]); free(edfhdr->edfparam); free(edfhdr); fclose(inputfile); textEdit1->append("Error, there is an incompatibility with the annotations.\n"); pushButton1->setEnabled(TRUE); return; } if(edfhdr->annots_not_read) { free_annotations(annotationlist[0]); free(edfhdr->edfparam); free(edfhdr); fclose(inputfile); textEdit1->append("Aborted.\n"); pushButton1->setEnabled(TRUE); return; } annotblock = annotationlist[0]; /***************** start conversion ******************************/ datarecords = edfhdr->datarecords; annot_signal_nr = edfhdr->annot_ch[0]; offset = edfhdr->edfparam[annot_signal_nr].buf_offset; if(edfhdr->edfplus) { annot_signal_size = edfhdr->edfparam[annot_signal_nr].smp_per_record * 2; } else { annot_signal_size = edfhdr->edfparam[annot_signal_nr].smp_per_record * 3; } fileheader = (char *)calloc(1, edfhdr->hdrsize); if(fileheader==NULL) { textEdit1->append("Malloc error, (fileheader).\n"); free_annotations(annotationlist[0]); free(edfhdr->edfparam); free(edfhdr); fclose(inputfile); pushButton1->setEnabled(TRUE); return; } readbuf = (char *)calloc(1, edfhdr->recordsize); if(readbuf==NULL) { textEdit1->append("Malloc error, (readbuf).\n"); free_annotations(annotationlist[0]); free(edfhdr->edfparam); free(edfhdr); free(fileheader); fclose(inputfile); pushButton1->setEnabled(TRUE); return; } rewind(inputfile); if(fread(fileheader, edfhdr->hdrsize, 1, inputfile) != 1) { textEdit1->append("Read error.\n"); free_annotations(annotationlist[0]); free(edfhdr->edfparam); free(edfhdr); free(fileheader); free(readbuf); fclose(inputfile); pushButton1->setEnabled(TRUE); return; } /////////////////////////////////////////////////////////////////// file_number = 1; strcpy(output_path, inputpath); remove_extension_from_filename(output_path); if(edfhdr->edfplus) { sprintf(output_path + strlen(output_path), "_%04i.edf", file_number); } else { sprintf(output_path + strlen(output_path), "_%04i.bdf", file_number); } strcpy(txt_string, "Creating file "); len = strlen(txt_string); get_filename_from_path(txt_string + len, output_path, MAX_PATH_LENGTH - len); textEdit1->append(QString::fromLocal8Bit(txt_string)); outputfile = fopeno(output_path, "w+b"); if(outputfile==NULL) { textEdit1->append("Error, can not open outputfile for writing.\n"); free_annotations(annotationlist[0]); free(edfhdr->edfparam); free(edfhdr); free(fileheader); free(readbuf); fclose(inputfile); pushButton1->setEnabled(TRUE); return; } if(fwrite(fileheader, edfhdr->hdrsize, 1, outputfile) != 1) { textEdit1->append("Write error.\n"); free_annotations(annotationlist[0]); free(edfhdr->edfparam); free(edfhdr); free(fileheader); free(readbuf); fclose(inputfile); fclose(outputfile); pushButton1->setEnabled(TRUE); return; } QProgressDialog progress("Processing file...", "Abort", 0, datarecords); progress.setWindowModality(Qt::WindowModal); progress.setMinimumDuration(200); progress_steps = datarecords / 100; if(progress_steps < 1) { progress_steps = 1; } datarecords_written = 0; new_hdr_timestamp = 0LL; former_timestamp = 0LL; next_timestamp = 0LL; chunk_starttime = 0LL; chunk_endtime = 0LL; tal = readbuf + offset; fseeko(inputfile, (long long)(edfhdr->hdrsize), SEEK_SET); for(datarecords_read=0; datarecords_readprocessEvents(); if(progress.wasCanceled() == TRUE) { textEdit1->append("Aborted.\n"); break; } } if(fread(readbuf, edfhdr->recordsize, 1, inputfile) != 1) { progress.reset(); textEdit1->append("Read error.\n"); free_annotations(annotationlist[0]); free(edfhdr->edfparam); free(edfhdr); free(fileheader); free(readbuf); fclose(inputfile); fclose(outputfile); pushButton1->setEnabled(TRUE); return; } if(edfhdr->nr_annot_chns>1) { for(i=1; inr_annot_chns; i++) { annot_signal_nr_2 = edfhdr->annot_ch[i]; offset_2 = edfhdr->edfparam[annot_signal_nr_2].buf_offset; if(edfhdr->edfplus) { annot_signal_size_2 = edfhdr->edfparam[annot_signal_nr_2].smp_per_record * 2; } else { annot_signal_size_2 = edfhdr->edfparam[annot_signal_nr_2].smp_per_record * 3; } memset(readbuf + offset_2, 0, annot_signal_size_2); } } next_timestamp = get_datarecord_timestamp(tal); if(!datarecords_read) { former_timestamp = next_timestamp - edfhdr->long_data_record_duration; } if(next_timestamp!=(former_timestamp + edfhdr->long_data_record_duration)) { chunk_endtime = next_timestamp; write_values_to_hdr(outputfile, new_hdr_timestamp, datarecords_written, edfhdr); annotblock = annotationlist[0]; annots_written = 0; if(annotblock!=NULL) { while(annotblock!=NULL) { if(((annotblock->onset>=chunk_starttime)||(file_number==1)) &&(annotblock->onsethdrsize + (annots_written * edfhdr->recordsize) + offset), SEEK_SET); for(cnt=1; ; cnt++) { if(fgetc(outputfile)==0) break; } fseeko(outputfile, 0LL, SEEK_CUR); cnt += fprintf(outputfile, "+%i", (int)((annotblock->onset - new_hdr_timestamp) / TIME_DIMENSION)); if(annotblock->onset%TIME_DIMENSION) { cnt += fprintf(outputfile, ".%07i", (int)((annotblock->onset - new_hdr_timestamp) % TIME_DIMENSION)); fseeko(outputfile, -1LL, SEEK_CUR); while(fgetc(outputfile)=='0') { fseeko(outputfile, -2LL, SEEK_CUR); cnt--; } } fseeko(outputfile, 0LL, SEEK_CUR); if(annotblock->duration[0]!=0) { fputc(21, outputfile); cnt++; cnt += fprintf(outputfile, "%s", annotblock->duration); } fputc(20, outputfile); cnt++; for(i = 0; i < (annot_signal_size - cnt - 2); i++) { if(annotblock->annotation[i]==0) break; fputc(annotblock->annotation[i], outputfile); cnt++; } fputc(20, outputfile); cnt++; for(i = cnt; i < annot_signal_size; i++) { fputc(0, outputfile); } annots_written++; } annotblock = annotblock->next_annotation; } } fclose(outputfile); datarecords_written = 0; new_hdr_timestamp = next_timestamp; new_hdr_timestamp -= next_timestamp % TIME_DIMENSION; chunk_starttime = next_timestamp; file_number++; strcpy(output_path, inputpath); remove_extension_from_filename(output_path); if(edfhdr->edfplus) { sprintf(output_path + strlen(output_path), "_%04i.edf", file_number); } else { sprintf(output_path + strlen(output_path), "_%04i.bdf", file_number); } strcpy(txt_string, "Creating file "); len = strlen(txt_string); get_filename_from_path(txt_string + len, output_path, MAX_PATH_LENGTH - len); textEdit1->append(txt_string); outputfile = fopeno(output_path, "w+b"); if(outputfile==NULL) { textEdit1->append("Error, can not open outputfile for writing.\n"); free_annotations(annotationlist[0]); free(edfhdr->edfparam); free(edfhdr); free(fileheader); free(readbuf); fclose(inputfile); pushButton1->setEnabled(TRUE); return; } if(fwrite(fileheader, edfhdr->hdrsize, 1, outputfile) != 1) { textEdit1->append("Write error.\n"); free_annotations(annotationlist[0]); free(edfhdr->edfparam); free(edfhdr); free(fileheader); free(readbuf); fclose(inputfile); fclose(outputfile); pushButton1->setEnabled(TRUE); return; } } cnt = sprintf(tal, "+%i", (int)((next_timestamp - new_hdr_timestamp) / TIME_DIMENSION)); if((next_timestamp - new_hdr_timestamp)%TIME_DIMENSION) { cnt += sprintf(tal + cnt, ".%07i", (int)((next_timestamp - new_hdr_timestamp) % TIME_DIMENSION)); for(i=cnt-1; i>0; i--) { if(tal[i]!='0') break; cnt--; } } tal[cnt++] = 20; tal[cnt++] = 20; for(i=cnt; irecordsize, 1, outputfile) != 1) { progress.reset(); textEdit1->append("Write error.\n"); free_annotations(annotationlist[0]); free(edfhdr->edfparam); free(edfhdr); free(fileheader); free(readbuf); fclose(inputfile); fclose(outputfile); pushButton1->setEnabled(TRUE); return; } datarecords_written++; former_timestamp = next_timestamp; } write_values_to_hdr(outputfile, new_hdr_timestamp, datarecords_written, edfhdr); annotblock = annotationlist[0]; annots_written = 0; if(annotblock!=NULL) { while(annotblock!=NULL) { if((annotblock->onset>=chunk_starttime)&&(annots_writtenhdrsize + (annots_written * edfhdr->recordsize) + offset), SEEK_SET); for(cnt=1; ; cnt++) { if(fgetc(outputfile)==0) break; } fseeko(outputfile, 0LL, SEEK_CUR); cnt += fprintf(outputfile, "+%i", (int)((annotblock->onset - new_hdr_timestamp) / TIME_DIMENSION)); if(annotblock->onset%TIME_DIMENSION) { cnt += fprintf(outputfile, ".%07i", (int)((annotblock->onset - new_hdr_timestamp) % TIME_DIMENSION)); fseeko(outputfile, -1LL, SEEK_CUR); while(fgetc(outputfile)=='0') { fseeko(outputfile, -2LL, SEEK_CUR); cnt--; } } fseeko(outputfile, 0LL, SEEK_CUR); if(annotblock->duration[0]!=0) { fputc(21, outputfile); cnt++; cnt += fprintf(outputfile, "%s", annotblock->duration); } fputc(20, outputfile); cnt++; for(i = 0; i < (annot_signal_size - cnt - 2); i++) { if(annotblock->annotation[i]==0) break; fputc(annotblock->annotation[i], outputfile); cnt++; } fputc(20, outputfile); cnt++; for(i = cnt; i < annot_signal_size; i++) { fputc(0, outputfile); } annots_written++; } annotblock = annotblock->next_annotation; } } free_annotations(annotationlist[0]); free(edfhdr->edfparam); free(edfhdr); free(fileheader); free(readbuf); fclose(inputfile); fclose(outputfile); progress.reset(); textEdit1->append("Done\n"); pushButton1->setEnabled(TRUE); } void UI_EDFDwindow::write_values_to_hdr(FILE *outputfile, long long timestamp, int datarecords, struct edfhdrblock *edfhdr) { int i; struct date_time_struct date_time; utc_to_date_time(edfhdr->utc_starttime + (timestamp / TIME_DIMENSION), &date_time); fseeko(outputfile, 98LL, SEEK_SET); fprintf(outputfile, "%02i-%s-%04i", date_time.day, date_time.month_str, date_time.year); fseeko(outputfile, 168LL, SEEK_SET); fprintf(outputfile, "%02i.%02i.%02i%02i.%02i.%02i", date_time.day, date_time.month, date_time.year % 100, date_time.hour, date_time.minute, date_time.second); fseeko(outputfile, 192LL, SEEK_SET); if(edfhdr->edfplus) { fprintf(outputfile, "EDF+C"); } else { fprintf(outputfile, "BDF+C"); } for(i=0; i<39; i++) { fputc(' ', outputfile); } fseeko(outputfile, 236LL, SEEK_SET); fprintf(outputfile, "%-8i", datarecords); } long long UI_EDFDwindow::get_datarecord_timestamp(char *str) { int i, len=8, hasdot=0, dotposition=0; long long value=0LL, radix; for(i=0; ; i++) { if(str[i]==20) { len = i; break; } } for(i=0; i=1; i--) { value += ((long long)(str[i] - 48)) * radix; radix *= 10; } radix = TIME_DIMENSION / 10; for(i=dotposition+1; i=1; i--) { value += ((long long)(str[i] - 48)) * radix; radix *= 10; } } if(str[0]=='-') { value = -value; } return(value); } void UI_EDFDwindow::free_annotations(struct annotationblock *annot) { if(annot==NULL) { return; } while(annot->next_annotation) { annot = annot->next_annotation; free(annot->former_annotation); } free(annot); } edfbrowser_153_source/PaxHeaders.2978/fino2edf.cpp0000644000175000001440000000013212251654530020347 xustar000000000000000030 mtime=1386699096.478032517 30 atime=1386699096.477032522 30 ctime=1386699096.478032517 edfbrowser_153_source/fino2edf.cpp0000644000175000001440000005062612251654530020111 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "fino2edf.h" #if defined(__APPLE__) || defined(__MACH__) || defined(__APPLE_CC__) #define fopeno fopen #else #define fseeko fseeko64 #define ftello ftello64 #define fopeno fopen64 #endif UI_FINO2EDFwindow::UI_FINO2EDFwindow(char *recent_dir, char *save_dir) { recent_opendir = recent_dir; recent_savedir = save_dir; myobjectDialog = new QDialog; myobjectDialog->setMinimumSize(QSize(600, 240)); myobjectDialog->setMaximumSize(QSize(600, 240)); myobjectDialog->setWindowTitle("Finometer to EDF converter"); myobjectDialog->setModal(TRUE); myobjectDialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); PatientnameLabel = new QLabel(myobjectDialog); PatientnameLabel->setGeometry(QRect(20, 20, 140, 16)); PatientnameLabel->setText("Subject name"); RecordingLabel = new QLabel(myobjectDialog); RecordingLabel->setGeometry(QRect(20, 50, 140, 16)); RecordingLabel->setText("Recording"); DatetimeLabel = new QLabel(myobjectDialog); DatetimeLabel->setGeometry(QRect(20, 80, 140, 16)); DatetimeLabel->setText("Startdate and time"); PatientnameLineEdit = new QLineEdit(myobjectDialog); PatientnameLineEdit->setGeometry(QRect(160, 20, 420, 21)); PatientnameLineEdit->setMaxLength(80); RecordingLineEdit = new QLineEdit(myobjectDialog); RecordingLineEdit->setGeometry(QRect(160, 50, 420, 21)); RecordingLineEdit->setMaxLength(80); RecordingLineEdit->setText("Finometer"); StartDatetimeedit = new QDateTimeEdit(myobjectDialog); StartDatetimeedit->setGeometry(QRect(160, 80, 140, 22)); StartDatetimeedit->setDisplayFormat("dd/MM/yyyy hh:mm:ss"); StartDatetimeedit->setDateTime(QDateTime::currentDateTime()); pushButton1 = new QPushButton(myobjectDialog); pushButton1->setGeometry(QRect(20, 190, 100, 26)); pushButton1->setText("Select File"); pushButton2 = new QPushButton(myobjectDialog); pushButton2->setGeometry(QRect(480, 190, 100, 26)); pushButton2->setText("Close"); QObject::connect(pushButton1, SIGNAL(clicked()), this, SLOT(SelectFileButton())); QObject::connect(pushButton2, SIGNAL(clicked()), myobjectDialog, SLOT(close())); myobjectDialog->exec(); } void UI_FINO2EDFwindow::SelectFileButton() { FILE *inputfile=NULL, *outputfile=NULL; int i, j, k, p, temp, separator=';', edfsignals=0, ok, timestep, new_smpl_time=0, datarecords, str_start, column, line_nr; char txt_string[2048], path[512], outputfilename[MAX_PATH_LENGTH], line[2048], scratchpad[128], labels[MAX_SIGNALS][17], phys_dim[MAX_SIGNALS][9], phys_min[MAX_SIGNALS][9], phys_max[MAX_SIGNALS][9], patientname[81], recording[81], datetime[17]; double sensitivity[MAX_SIGNALS], new_value[MAX_SIGNALS], old_value[MAX_SIGNALS]; union{ short two; char one[2]; } var; for(j=0; jtext().toLatin1().data()))) { QMessageBox messagewindow(QMessageBox::Critical, "Invalid input", "Please enter a subjectname."); messagewindow.exec(); enable_widgets(TRUE); return; } if(!(strlen(RecordingLineEdit->text().toLatin1().data()))) { QMessageBox messagewindow(QMessageBox::Critical, "Invalid input", "Please enter a recordingdescription."); messagewindow.exec(); enable_widgets(TRUE); return; } strcpy(path, QFileDialog::getOpenFileName(0, "Select inputfile", QString::fromLocal8Bit(recent_opendir), "Text files (*.txt *.TXT)").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) { snprintf(txt_string, 2048, "Can not open file %s for reading.", path); QMessageBox messagewindow(QMessageBox::Critical, "Error", txt_string); messagewindow.exec(); enable_widgets(TRUE); return; } /***************** check if the txtfile is valid ******************************/ rewind(inputfile); if(fread(scratchpad, 5, 1, inputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while reading the inputfile."); messagewindow.exec(); fclose(inputfile); enable_widgets(TRUE); return; } if(strncmp(scratchpad, "\"T\";", 4)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Unknown data in file (1)."); messagewindow.exec(); fclose(inputfile); enable_widgets(TRUE); return; } while(1) { temp = fgetc(inputfile); if(temp==EOF) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Reached end of file unexpectedly (2)."); messagewindow.exec(); fclose(inputfile); enable_widgets(TRUE); return; } if(temp=='\n') break; } if(fread(scratchpad, 2, 1, inputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while reading inputfile (3)."); messagewindow.exec(); fclose(inputfile); enable_widgets(TRUE); return; } if(strncmp(scratchpad, "\"s\";", 4)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Unknown data in file (4)."); messagewindow.exec(); fclose(inputfile); enable_widgets(TRUE); return; } /***************** collect items *****************************************/ rewind(inputfile); while(1) { temp = fgetc(inputfile); if(temp==EOF) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Reached end of file unexpectedly (5)."); messagewindow.exec(); fclose(inputfile); enable_widgets(TRUE); return; } if(temp==separator) { break; } } i = 0; while(temp!='\n') { temp = fgetc(inputfile); if(temp==EOF) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Reached end of file unexpectedly (6)."); messagewindow.exec(); fclose(inputfile); enable_widgets(TRUE); return; } if(temp=='\r') { continue; } if((temp==separator)||(temp=='\n')) { if(edfsignals>=MAX_SIGNALS) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Too many labels/signals (7)."); messagewindow.exec(); fclose(inputfile); enable_widgets(TRUE); return; } line[i] = 0; ok = 0; if(!strcmp(line, "\" reSYS\"")) { strcpy(labels[edfsignals], "reSYS "); strcpy(phys_dim[edfsignals], "mmHg "); strcpy(phys_min[edfsignals], "-1024 "); strcpy(phys_max[edfsignals], "1024 "); sensitivity[edfsignals] = 31.0; ok = 1; } if(!strcmp(line, "\" fiSYS\"")) { strcpy(labels[edfsignals], "fiSYS "); strcpy(phys_dim[edfsignals], "mmHg "); strcpy(phys_min[edfsignals], "-1024 "); strcpy(phys_max[edfsignals], "1024 "); sensitivity[edfsignals] = 31.0; ok = 1; } if(!strcmp(line, "\" reDIA\"")) { strcpy(labels[edfsignals], "reDIA "); strcpy(phys_dim[edfsignals], "mmHg "); strcpy(phys_min[edfsignals], "-1024 "); strcpy(phys_max[edfsignals], "1024 "); sensitivity[edfsignals] = 31.0; ok = 1; } if(!strcmp(line, "\" fiDIA\"")) { strcpy(labels[edfsignals], "fiDIA "); strcpy(phys_dim[edfsignals], "mmHg "); strcpy(phys_min[edfsignals], "-1024 "); strcpy(phys_max[edfsignals], "1024 "); sensitivity[edfsignals] = 31.0; ok = 1; } if(!strcmp(line, "\" reMAP\"")) { strcpy(labels[edfsignals], "reMAP "); strcpy(phys_dim[edfsignals], "mmHg "); strcpy(phys_min[edfsignals], "-1024 "); strcpy(phys_max[edfsignals], "1024 "); sensitivity[edfsignals] = 31.0; ok = 1; } if(!strcmp(line, "\" fiMAP\"")) { strcpy(labels[edfsignals], "fiMAP "); strcpy(phys_dim[edfsignals], "mmHg "); strcpy(phys_min[edfsignals], "-1024 "); strcpy(phys_max[edfsignals], "1024 "); sensitivity[edfsignals] = 31.0; ok = 1; } if(!strcmp(line, "\" HR\"")) { strcpy(labels[edfsignals], "HR "); strcpy(phys_dim[edfsignals], "bpm "); strcpy(phys_min[edfsignals], "-1024 "); strcpy(phys_max[edfsignals], "1024 "); sensitivity[edfsignals] = 31.0; ok = 1; } if(!strcmp(line, "\" IBI\"")) { strcpy(labels[edfsignals], "IBI "); strcpy(phys_dim[edfsignals], "s "); strcpy(phys_min[edfsignals], "-31.744 "); strcpy(phys_max[edfsignals], "31.744 "); sensitivity[edfsignals] = 1000.0; ok = 1; } if(!strcmp(line, "\" SV\"")) { strcpy(labels[edfsignals], "SV "); strcpy(phys_dim[edfsignals], "ml "); strcpy(phys_min[edfsignals], "-1024 "); strcpy(phys_max[edfsignals], "1024 "); sensitivity[edfsignals] = 31.0; ok = 1; } if(!strcmp(line, "\" CO\"")) { strcpy(labels[edfsignals], "CO "); strcpy(phys_dim[edfsignals], "lpm "); strcpy(phys_min[edfsignals], "-1024 "); strcpy(phys_max[edfsignals], "1024 "); sensitivity[edfsignals] = 31.0; ok = 1; } if(!strcmp(line, "\" EJT\"")) { strcpy(labels[edfsignals], "EJT "); strcpy(phys_dim[edfsignals], "s "); strcpy(phys_min[edfsignals], "-1024 "); strcpy(phys_max[edfsignals], "1024 "); sensitivity[edfsignals] = 31.0; ok = 1; } if(!strcmp(line, "\" TPR\"")) { strcpy(labels[edfsignals], "TPR "); strcpy(phys_dim[edfsignals], "MU "); strcpy(phys_min[edfsignals], "-1024 "); strcpy(phys_max[edfsignals], "1024 "); sensitivity[edfsignals] = 31.0; ok = 1; } if(!strcmp(line, "\" Artifact\"")) { strcpy(labels[edfsignals], "Artifact "); strcpy(phys_dim[edfsignals], "_TPSROD2"); strcpy(phys_min[edfsignals], "0 "); strcpy(phys_max[edfsignals], "10000000"); sensitivity[edfsignals] = 0.0063488; ok = 1; } if(!strcmp(line, "\" Zao\"")) { strcpy(labels[edfsignals], "Zao "); strcpy(phys_dim[edfsignals], "mMU "); strcpy(phys_min[edfsignals], "-1024 "); strcpy(phys_max[edfsignals], "1024 "); sensitivity[edfsignals] = 31.0; ok = 1; } if(!strcmp(line, "\" Cwk\"")) { strcpy(labels[edfsignals], "Cwk "); strcpy(phys_dim[edfsignals], "MU "); strcpy(phys_min[edfsignals], "-1024 "); strcpy(phys_max[edfsignals], "1024 "); sensitivity[edfsignals] = 31.0; ok = 1; } if(!strcmp(line, "\" Height\"")) { strcpy(labels[edfsignals], "Height "); strcpy(phys_dim[edfsignals], "mmHg "); strcpy(phys_min[edfsignals], "-1024 "); strcpy(phys_max[edfsignals], "1024 "); sensitivity[edfsignals] = 31.0; ok = 1; } if(!ok) { snprintf(txt_string, 2048, "Found unknown label/signal: %s", line); QMessageBox messagewindow(QMessageBox::Critical, "Error", txt_string); messagewindow.exec(); fclose(inputfile); enable_widgets(TRUE); return; } edfsignals++; i = 0; } if(temp==separator) { continue; } line[i++] = temp; } if(!edfsignals) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There are no labels/signals."); messagewindow.exec(); fclose(inputfile); enable_widgets(TRUE); return; } p = sprintf(patientname, "%s", PatientnameLineEdit->text().toLatin1().data()); latin1_to_ascii(patientname, p); for( ; p<80; p++) { patientname[p] = ' '; } patientname[80] = 0; p = sprintf(recording, "%s", RecordingLineEdit->text().toLatin1().data()); latin1_to_ascii(recording, p); for( ; p<80; p++) { recording[p] = ' '; } recording[80] = 0; sprintf(datetime, "%02i.%02i.%02i%02i.%02i.%02i", StartDatetimeedit->date().day(), StartDatetimeedit->date().month(), StartDatetimeedit->date().year() % 100, StartDatetimeedit->time().hour(), StartDatetimeedit->time().minute(), StartDatetimeedit->time().second()); datetime[16] = 0; /***************** write header *****************************************/ get_filename_from_path(outputfilename, path, MAX_PATH_LENGTH); remove_extension_from_filename(outputfilename); strcat(outputfilename, "_finometer.edf"); path[0] = 0; if(recent_savedir[0]!=0) { strcpy(path, recent_savedir); strcat(path, "/"); } strcat(path, outputfilename); 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); outputfile = fopeno(path, "wb"); if(outputfile==NULL) { snprintf(txt_string, 2048, "Can not open file %s for writing.", path); QMessageBox messagewindow(QMessageBox::Critical, "Error", txt_string); messagewindow.exec(); enable_widgets(TRUE); fclose(inputfile); return; } fprintf(outputfile, "0 "); fprintf(outputfile, "%s", patientname); fprintf(outputfile, "%s", recording); fprintf(outputfile, "%s", datetime); fprintf(outputfile, "%-8i", 256 * edfsignals + 256); fprintf(outputfile, " "); fprintf(outputfile, "-1 "); fprintf(outputfile, "0.01 "); fprintf(outputfile, "%-4i", edfsignals); for(i=0; i1) break; } QApplication::setOverrideCursor(Qt::WaitCursor); for(k=0; k<10; k++) qApp->processEvents(); i = 0; column = 0; datarecords = 0; str_start = 0; line_nr = 2; while(1) { temp = fgetc(inputfile); if(temp==EOF) { for(k=0; k31744) temp = 31744; if(temp<-31744) temp = -31744; var.two = (short)temp; fputc(var.one[0], outputfile); fputc(var.one[1], outputfile); } datarecords++; break; } line[i] = temp; /**************************************/ if(line[i]==',') { line[i] = '.'; } if((line[i]==separator)||(line[i]=='\n')) { if(column) { new_value[column-1] = atof(line + str_start); } else { new_smpl_time = (int)(atof(line + str_start) * 100.0); } if(line[i]=='\n') { /**************************************/ line_nr++; if(column!=edfsignals) { QApplication::restoreOverrideCursor(); snprintf(txt_string, 2048, "Number of separators in line %i is wrong.", line_nr); QMessageBox messagewindow(QMessageBox::Critical, "Error", txt_string); messagewindow.exec(); fclose(inputfile); fclose(outputfile); enable_widgets(TRUE); return; } timestep = new_smpl_time - datarecords; if(timestep<=0) { QApplication::restoreOverrideCursor(); snprintf(txt_string, 2048, "Timestep <= 0 in line %i.", line_nr); QMessageBox messagewindow(QMessageBox::Critical, "Error", txt_string); messagewindow.exec(); fclose(inputfile); fclose(outputfile); enable_widgets(TRUE); return; } for(j=0; j31744) temp = 31744; if(temp<-31744) temp = -31744; var.two = (short)temp; fputc(var.one[0], outputfile); fputc(var.one[1], outputfile); } datarecords++; } for(j=0; j2046) { QApplication::restoreOverrideCursor(); snprintf(txt_string, 2048, "Line %i is too long.", line_nr); QMessageBox messagewindow(QMessageBox::Critical, "Error", txt_string); messagewindow.exec(); fclose(inputfile); fclose(outputfile); enable_widgets(TRUE); return; } } QApplication::restoreOverrideCursor(); fseeko(outputfile, 236LL, SEEK_SET); fprintf(outputfile, "%-8i", datarecords); if(fclose(outputfile)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while closing outputfile."); messagewindow.exec(); enable_widgets(TRUE); fclose(inputfile); return; } if(fclose(inputfile)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while closing inputfile."); messagewindow.exec(); } snprintf(txt_string, 2048, "Done, EDF file is located at %s", path); QMessageBox messagewindow(QMessageBox::Information, "Ready", txt_string); messagewindow.setIconPixmap(QPixmap(":/images/ok.png")); messagewindow.exec(); enable_widgets(TRUE); } void UI_FINO2EDFwindow::enable_widgets(bool toggle) { StartDatetimeedit->setEnabled(toggle); PatientnameLineEdit->setEnabled(toggle); RecordingLineEdit->setEnabled(toggle); pushButton1->setEnabled(toggle); pushButton2->setEnabled(toggle); } edfbrowser_153_source/PaxHeaders.2978/save_montage_dialog.h0000644000175000001440000000013212251654530022307 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/save_montage_dialog.h0000644000175000001440000000367412251654530022052 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef SAVEMONTAGEFORM1_H #define SAVEMONTAGEFORM1_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "mainwindow.h" #include "xml.h" class UI_Mainwindow; class UI_SaveMontagewindow : public QObject { Q_OBJECT public: UI_SaveMontagewindow(QWidget *parent); UI_Mainwindow *mainwindow; private: QDialog *SaveMontageDialog; QLabel *label1; QListWidget *filelist; QPushButton *CloseButton, *SaveButton; private slots: void SaveButtonClicked(); }; #endif // SAVEMONTAGEFORM1_H edfbrowser_153_source/PaxHeaders.2978/gpl.txt0000644000175000001440000000013212251654530017472 xustar000000000000000030 mtime=1386699096.499032406 30 atime=1386699096.499032406 30 ctime=1386699096.499032406 edfbrowser_153_source/gpl.txt0000644000175000001440000003624612251654530017236 0ustar00novarausers00000000000000This is free software, it is experimental and available under the GPL License version 2. Despite this software is intend to be useful, there is no warranty, Use this software at your own risk! EDFbrowser may NOT be used in safety-critical applications, such as life-support medical systems. The author is NOT responsible for any consequences. For research and educational purpose only. GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS edfbrowser_153_source/PaxHeaders.2978/signalcurve.cpp0000644000175000001440000000013212251654530021175 xustar000000000000000030 mtime=1386699096.479032511 30 atime=1386699096.479032511 30 ctime=1386699096.479032511 edfbrowser_153_source/signalcurve.cpp0000644000175000001440000017466012251654530020744 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "signalcurve.h" SignalCurve::SignalCurve(QWidget *w_parent) : QWidget(w_parent) { setAttribute(Qt::WA_OpaquePaintEvent); recent_savedir[0] = 0; SignalColor = Qt::blue; tracewidth = 0; BackgroundColor = Qt::gray; RasterColor = Qt::darkGray; BorderColor = Qt::lightGray; RulerColor = Qt::black; TextColor = Qt::black; crosshair_1_color = Qt::red; Marker1Pen.setStyle(Qt::DashLine); Marker1Pen.setColor(Qt::yellow); Marker2Pen.setStyle(Qt::DashLine); Marker2Pen.setColor(Qt::yellow); bufsize = 0; dbuf = NULL; fbuf = NULL; ibuf = NULL; bordersize = 60; drawHruler = 1; drawVruler = 1; h_ruler_startvalue = 0.0; h_ruler_endvalue = 100.0; h_ruler_precision = 2; drawcurve_before_raster = 0; h_label[0] = 0; v_label[0] = 0; upperlabel1[0] = 0; upperlabel2[0] = 0; lowerlabel[0] = 0; max_value = 100.0; min_value = -100.0; extra_button = 0; extra_button_txt[0] = 0; use_move_events = 0; crosshair_1_active = 0; crosshair_1_moving = 0; crosshair_1_value = 0.0; crosshair_1_value_2 = 0.0; crosshair_1_x_position = 0; marker_1_position = 0.25; marker_1_moving = 0; marker_2_position = 0.75; marker_2_moving = 0; fillsurface = 0; cursorEnabled = TRUE; printEnabled = TRUE; dashBoardEnabled = TRUE; updates_enabled = TRUE; Marker1Enabled = FALSE; Marker1MovableEnabled = FALSE; Marker2Enabled = FALSE; Marker2MovableEnabled = FALSE; curveUpSideDown = FALSE; line1Enabled = FALSE; spectrum_color = NULL; old_w = 10000; } void SignalCurve::clear() { dbuf = NULL; fbuf = NULL; ibuf = NULL; bufsize = 0; use_move_events = 0; crosshair_1_active = 0; crosshair_1_moving = 0; crosshair_1_value = 0.0; crosshair_1_value_2 = 0.0; crosshair_1_x_position = 0; marker_1_position = 0.25; marker_2_position = 0.75; Marker1Enabled = FALSE; Marker1MovableEnabled = FALSE; Marker2Enabled = FALSE; Marker2MovableEnabled = FALSE; line1Enabled = FALSE; update(); } void SignalCurve::mousePressEvent(QMouseEvent *press_event) { int m_x, m_y; setFocus(Qt::MouseFocusReason); w = width(); h = height(); m_x = press_event->x() - bordersize; m_y = press_event->y() - bordersize; if(m_x < 0 || m_x > (w - (bordersize * 2)) || m_y < 0 || m_y > (h - (bordersize * 2))) { return; } if(press_event->button()==Qt::LeftButton) { if(printEnabled == TRUE) { if((m_y<21)&&(m_y>3)&&(m_x>((w - (bordersize * 2)) - 43))&&(m_x<((w - (bordersize * 2)) - 3))) { exec_sidemenu(); return; } } if(dashBoardEnabled == TRUE) { if((m_y<61)&&(m_y>43)&&(m_x>((w - (bordersize * 2)) - 43))&&(m_x<((w - (bordersize * 2)) - 3))) { emit dashBoardClicked(); return; } } if(cursorEnabled == TRUE) { if((m_y<41)&&(m_y>23)&&(m_x>((w - (bordersize * 2)) - 43))&&(m_x<((w - (bordersize * 2)) - 3))) { if(crosshair_1_active) { crosshair_1_active = 0; crosshair_1_moving = 0; use_move_events = 0; setMouseTracking(FALSE); } else { crosshair_1_active = 1; if(!crosshair_1_x_position) { crosshair_1_value = 0.0; crosshair_1_x_position = (w - (bordersize * 2)) / 2; crosshair_1_y_position = (h - (bordersize * 2)) / 2; mouse_old_x = crosshair_1_x_position; mouse_old_y = crosshair_1_y_position; } } update(); return; } } if(crosshair_1_active) { if((m_y<(crosshair_1_y_position + 15))&&(m_y>(crosshair_1_y_position - 25))&&(m_x>crosshair_1_x_position)&&(m_x<(crosshair_1_x_position + 65))) { crosshair_1_moving = 1; use_move_events = 1; setMouseTracking(TRUE); mouse_old_x = m_x; mouse_old_y = m_y; } if(m_x>(crosshair_1_x_position-10)&&(m_x<(crosshair_1_x_position + 10))) { crosshair_1_moving = 1; use_move_events = 1; setMouseTracking(TRUE); mouse_old_x = m_x; mouse_old_y = m_y; } } if((Marker1MovableEnabled == TRUE) && (Marker1Enabled == TRUE)) { marker_1_x_position = (w - (bordersize * 2)) * marker_1_position; if(m_x > (marker_1_x_position - 5) && (m_x < (marker_1_x_position + 5))) { marker_1_moving = 1; use_move_events = 1; setMouseTracking(TRUE); mouse_old_x = m_x; mouse_old_y = m_y; } } if((Marker2MovableEnabled == TRUE) && (Marker2Enabled == TRUE)) { marker_2_x_position = (w - (bordersize * 2)) * marker_2_position; if(m_x > (marker_2_x_position - 5) && (m_x < (marker_2_x_position + 5))) { marker_2_moving = 1; use_move_events = 1; setMouseTracking(TRUE); mouse_old_x = m_x; mouse_old_y = m_y; } } } } void SignalCurve::mouseReleaseEvent(QMouseEvent *) { crosshair_1_moving = 0; marker_1_moving = 0; marker_2_moving = 0; use_move_events = 0; setMouseTracking(FALSE); } void SignalCurve::mouseMoveEvent(QMouseEvent *move_event) { if(!use_move_events) { return; } mouse_x = move_event->x() - bordersize; mouse_y = move_event->y() - bordersize; if(crosshair_1_moving) { crosshair_1_x_position += (mouse_x - mouse_old_x); mouse_old_x = mouse_x; if(crosshair_1_x_position<2) { crosshair_1_x_position = 2; } if(crosshair_1_x_position>(w-(bordersize * 2) -2)) { crosshair_1_x_position = w-(bordersize * 2) -2; } crosshair_1_y_position += (mouse_y - mouse_old_y); mouse_old_y = mouse_y; if(crosshair_1_y_position<25) { crosshair_1_y_position = 25; } if(crosshair_1_y_position>(h-(bordersize * 2) -25)) { crosshair_1_y_position = h-(bordersize * 2) -25; } } if(marker_1_moving) { marker_1_x_position += (mouse_x - mouse_old_x); mouse_old_x = mouse_x; if(marker_1_x_position<2) { marker_1_x_position = 2; } if(marker_1_x_position>(w-(bordersize * 2) - 2)) { marker_1_x_position = w-(bordersize * 2) - 2; } marker_1_position = (double)marker_1_x_position / (double)(w-(bordersize * 2)); emit markerHasMoved(); } if(marker_2_moving) { marker_2_x_position += (mouse_x - mouse_old_x); mouse_old_x = mouse_x; if(marker_2_x_position<2) { marker_2_x_position = 2; } if(marker_2_x_position>(w-(bordersize * 2) - 2)) { marker_2_x_position = w-(bordersize * 2) - 2; } marker_2_position = (double)marker_2_x_position / (double)(w-(bordersize * 2)); emit markerHasMoved(); } update(); } void SignalCurve::shiftCursorIndexLeft(int idxs) { int idx; double ppi; if(!crosshair_1_active) { return; } if(bufsize < 2) { return; } w = width(); ppi = (double)(w-(bordersize * 2)) / (double)bufsize; idx = (double)crosshair_1_x_position / ppi; idx -= idxs; if(idx < 0) { idx = 0; } if(idx >= bufsize) { idx = bufsize - 1; } crosshair_1_x_position = (double)idx * ppi + (0.5 * ppi); update(); } void SignalCurve::shiftCursorIndexRight(int idxs) { int idx; double ppi; if(!crosshair_1_active) { return; } if(bufsize < 2) { return; } w = width(); ppi = (double)(w-(bordersize * 2)) / (double)bufsize; idx = (double)crosshair_1_x_position / ppi; idx += idxs; if(idx < 0) { idx = 0; } if(idx >= bufsize) { idx = bufsize - 1; } crosshair_1_x_position = (double)idx * ppi + (0.5 * ppi); update(); } void SignalCurve::shiftCursorPixelsLeft(int pixels) { if(!crosshair_1_active) { return; } crosshair_1_x_position -= pixels; if(crosshair_1_x_position<2) { crosshair_1_x_position = 2; } update(); } void SignalCurve::shiftCursorPixelsRight(int pixels) { if(!crosshair_1_active) { return; } w = width(); crosshair_1_x_position += pixels; if(crosshair_1_x_position>(w-(bordersize * 2) -2)) { crosshair_1_x_position = w-(bordersize * 2) -2; } update(); } void SignalCurve::resizeEvent(QResizeEvent *resize_event) { if(crosshair_1_active) { crosshair_1_x_position *= ((double)(width() - (bordersize * 2)) / (double)(old_w - (bordersize * 2))); } QWidget::resizeEvent(resize_event); } void SignalCurve::exec_sidemenu() { sidemenu = new QDialog(this); if(extra_button) { sidemenu->setMinimumSize(QSize(120, 190)); sidemenu->setMaximumSize(QSize(120, 190)); } else { sidemenu->setMinimumSize(QSize(120, 160)); sidemenu->setMaximumSize(QSize(120, 160)); } sidemenu->setWindowTitle("Print"); sidemenu->setModal(TRUE); sidemenu->setAttribute(Qt::WA_DeleteOnClose, TRUE); sidemenuButton1 = new QPushButton(sidemenu); sidemenuButton1->setGeometry(10, 10, 100, 20); sidemenuButton1->setText("to printer"); sidemenuButton2 = new QPushButton(sidemenu); sidemenuButton2->setGeometry(10, 40, 100, 20); sidemenuButton2->setText("to Postscript"); sidemenuButton3 = new QPushButton(sidemenu); sidemenuButton3->setGeometry(10, 70, 100, 20); sidemenuButton3->setText("to PDF"); sidemenuButton4 = new QPushButton(sidemenu); sidemenuButton4->setGeometry(10, 100, 100, 20); sidemenuButton4->setText("to Image"); sidemenuButton5 = new QPushButton(sidemenu); sidemenuButton5->setGeometry(10, 130, 100, 20); sidemenuButton5->setText("to ASCII"); if(extra_button) { sidemenuButton6 = new QPushButton(sidemenu); sidemenuButton6->setGeometry(10, 160, 100, 20); sidemenuButton6->setText(extra_button_txt); } QObject::connect(sidemenuButton1, SIGNAL(clicked()), this, SLOT(print_to_printer())); QObject::connect(sidemenuButton2, SIGNAL(clicked()), this, SLOT(print_to_postscript())); QObject::connect(sidemenuButton3, SIGNAL(clicked()), this, SLOT(print_to_pdf())); QObject::connect(sidemenuButton4, SIGNAL(clicked()), this, SLOT(print_to_image())); QObject::connect(sidemenuButton5, SIGNAL(clicked()), this, SLOT(print_to_ascii())); if(extra_button) { QObject::connect(sidemenuButton6, SIGNAL(clicked()), this, SLOT(send_button_event())); } sidemenu->exec(); } void SignalCurve::send_button_event() { emit extra_button_clicked(); sidemenu->close(); } void SignalCurve::create_button(const char *txt) { extra_button = 1; strncpy(extra_button_txt, txt, 16); extra_button_txt[15] = 0; } void SignalCurve::backup_colors_for_printing(void) { backup_color_1 = SignalColor; SignalColor = Qt::black; backup_color_2 = RasterColor; RasterColor = Qt::black; backup_color_3 = BorderColor; BorderColor = Qt::black; backup_color_4 = RulerColor; RulerColor = Qt::black; backup_color_5 = TextColor; TextColor = Qt::black; backup_color_6 = Marker1Pen.color(); Marker1Pen.setColor(Qt::black); } void SignalCurve::restore_colors_after_printing(void) { SignalColor = backup_color_1; RasterColor = backup_color_2; BorderColor = backup_color_3; RulerColor = backup_color_4; TextColor = backup_color_5; Marker1Pen.setColor(backup_color_6); } void SignalCurve::print_to_ascii() { int i; char path[SC_MAX_PATH_LEN]; FILE *outputfile; path[0] = 0; if(recent_savedir[0]!=0) { strcpy(path, recent_savedir); strcat(path, "/"); } strcat(path, "curve.csv"); strcpy(path, QFileDialog::getSaveFileName(0, "Print to ASCII / CSV", QString::fromLocal8Bit(path), "ASCII / CSV files (*.csv *.CSV *.txt *.TXT)").toLocal8Bit().data()); if(!strcmp(path, "")) { sidemenu->close(); return; } get_directory_from_path(recent_savedir, path, SC_MAX_PATH_LEN); outputfile = fopen(path, "wb"); if(path == NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not open outputfile for writing."); messagewindow.exec(); return; } if(ibuf != NULL) { for(i=0; iclose(); } void SignalCurve::print_to_postscript() { char path[SC_MAX_PATH_LEN]; path[0] = 0; if(recent_savedir[0]!=0) { strcpy(path, recent_savedir); strcat(path, "/"); } strcat(path, "curve.ps"); strcpy(path, QFileDialog::getSaveFileName(0, "Print to PostScript", QString::fromLocal8Bit(path), "PostScript files (*.ps *.PS)").toLocal8Bit().data()); if(!strcmp(path, "")) { sidemenu->close(); return; } get_directory_from_path(recent_savedir, path, SC_MAX_PATH_LEN); QPrinter curve_printer(QPrinter::HighResolution); curve_printer.setOutputFormat(QPrinter::PostScriptFormat); curve_printer.setOutputFileName(path); curve_printer.setPageSize(QPrinter::A4); curve_printer.setOrientation(QPrinter::Landscape); backup_colors_for_printing(); QPainter paint(&curve_printer); drawWidget_to_printer(&paint, curve_printer.pageRect().width(), curve_printer.pageRect().height()); restore_colors_after_printing(); sidemenu->close(); } void SignalCurve::print_to_pdf() { char path[SC_MAX_PATH_LEN]; path[0] = 0; if(recent_savedir[0]!=0) { strcpy(path, recent_savedir); strcat(path, "/"); } strcat(path, "curve.pdf"); strcpy(path, QFileDialog::getSaveFileName(0, "Print to PDF", QString::fromLocal8Bit(path), "PDF files (*.pdf *.PDF)").toLocal8Bit().data()); if(!strcmp(path, "")) { sidemenu->close(); return; } get_directory_from_path(recent_savedir, path, SC_MAX_PATH_LEN); QPrinter curve_printer(QPrinter::HighResolution); curve_printer.setOutputFormat(QPrinter::PdfFormat); curve_printer.setOutputFileName(path); curve_printer.setPageSize(QPrinter::A4); curve_printer.setOrientation(QPrinter::Landscape); backup_colors_for_printing(); QPainter paint(&curve_printer); drawWidget_to_printer(&paint, curve_printer.pageRect().width(), curve_printer.pageRect().height()); restore_colors_after_printing(); sidemenu->close(); } void SignalCurve::print_to_image() { char path[SC_MAX_PATH_LEN]; path[0] = 0; if(recent_savedir[0]!=0) { strcpy(path, recent_savedir); strcat(path, "/"); } strcat(path, "curve.png"); strcpy(path, QFileDialog::getSaveFileName(0, "Print to Image", QString::fromLocal8Bit(path), "PNG files (*.png *.PNG)").toLocal8Bit().data()); if(!strcmp(path, "")) { sidemenu->close(); return; } get_directory_from_path(recent_savedir, path, SC_MAX_PATH_LEN); QPixmap pixmap(width(), height()); QPainter paint(&pixmap); drawWidget(&paint, width(), height()); pixmap.save(path, "PNG", 90); sidemenu->close(); } void SignalCurve::print_to_printer() { QPrinter curve_printer(QPrinter::HighResolution); curve_printer.setOutputFormat(QPrinter::NativeFormat); curve_printer.setPageSize(QPrinter::A4); curve_printer.setOrientation(QPrinter::Landscape); QPrintDialog printerdialog(&curve_printer, this); printerdialog.setWindowTitle("Print"); if(!(printerdialog.exec()==QDialog::Accepted)) { sidemenu->close(); return; } backup_colors_for_printing(); QPainter paint(&curve_printer); drawWidget_to_printer(&paint, curve_printer.pageRect().width(), curve_printer.pageRect().height()); restore_colors_after_printing(); sidemenu->close(); } void SignalCurve::drawWidget_to_printer(QPainter *painter, int curve_w, int curve_h) { int i, j, precision, bordersize_backup=0, p_w, p_divisor, p_range, p_multiplier, p_ruler_startvalue, p_ruler_endvalue, p_tmp, p_h, p2_divisor, p2_range, p2_multiplier, p2_ruler_startvalue, p2_ruler_endvalue, p2_tmp; char str[128]; double v_sens, offset, h_step, value, p_factor, p_pixels_per_unit, p2_pixels_per_unit; QString q_str; QFont curve_font; QPen printer_pen; curve_w -= 30; curve_h -= 30; p_factor = (double)curve_w / width(); bordersize_backup = bordersize; bordersize *= p_factor; curve_font.setFamily("Arial"); curve_font.setPixelSize((int)((double)curve_w / 104.0)); painter->setFont(curve_font); if((curve_w < ((bordersize * 2) + 5)) || (curve_h < ((bordersize * 2) + 5))) { bordersize = bordersize_backup; return; } printer_pen = QPen(Qt::SolidPattern, 2, Qt::SolidLine, Qt::SquareCap, Qt::BevelJoin); printer_pen.setColor(Qt::black); painter->setPen(printer_pen); /////////////////////////////////// draw the window /////////////////////////////////////////// painter->drawLine(0, 0, 0, curve_h); painter->drawLine(0, 0, curve_w, 0); painter->drawLine(curve_w, curve_h, curve_w, 0); painter->drawLine(curve_w, curve_h, 0, curve_h); /////////////////////////////////// draw the rulers /////////////////////////////////////////// p_w = curve_w - bordersize - bordersize; p_multiplier = 1; while((h_ruler_endvalue * p_multiplier) < 10000.0) { p_multiplier *= 10; if(p_multiplier > 10000000) { break; } } p_ruler_startvalue = h_ruler_startvalue * p_multiplier; p_ruler_endvalue = h_ruler_endvalue * p_multiplier; p_range = p_ruler_endvalue - p_ruler_startvalue; p_pixels_per_unit = (double)p_w / (double)p_range; p_divisor = 1; while((p_range / p_divisor) > 10) { p_divisor *= 2; if((p_range / p_divisor) <= 10) { break; } p_divisor /= 2; p_divisor *= 5; if((p_range / p_divisor) <= 10) { break; } p_divisor *= 2; } if(drawHruler && (bordersize > (19 * p_factor))) { painter->drawLine(bordersize, curve_h - bordersize + (5 * p_factor), curve_w - bordersize, curve_h - bordersize + (5 * p_factor)); h_ruler_precision = 0; if((h_ruler_endvalue < 10.0) && (h_ruler_endvalue > -10.0) && (h_ruler_startvalue < 10.0) && (h_ruler_startvalue > -10.0)) { h_ruler_precision = 1; if((h_ruler_endvalue < 1.0) && (h_ruler_endvalue > -1.0) && (h_ruler_startvalue < 1.0) && (h_ruler_startvalue > -1.0)) { h_ruler_precision = 2; if((h_ruler_endvalue < 0.1) && (h_ruler_endvalue > -0.1) && (h_ruler_startvalue < 0.1) && (h_ruler_startvalue > -0.1)) { h_ruler_precision = 3; if((h_ruler_endvalue < 0.01) && (h_ruler_endvalue > -0.01) && (h_ruler_startvalue < 0.01) && (h_ruler_startvalue > -0.01)) { h_ruler_precision = 4; } } } } for(i = (p_ruler_startvalue / p_divisor) * p_divisor; i <= p_ruler_endvalue; i += p_divisor) { if(i < p_ruler_startvalue) { continue; } q_str.setNum((double)i / (double)p_multiplier, 'f', h_ruler_precision); p_tmp = (double)(i - p_ruler_startvalue) * p_pixels_per_unit; painter->drawText(bordersize + p_tmp - (30 * p_factor), curve_h - bordersize + (18 * p_factor), 60 * p_factor, 16 * p_factor, Qt::AlignCenter | Qt::TextSingleLine, q_str); painter->drawLine(bordersize + p_tmp, curve_h - bordersize + (5 * p_factor), bordersize + p_tmp, curve_h - bordersize + ((5 + 10) * p_factor)); } painter->drawText(curve_w - bordersize + (20 * p_factor), curve_h - bordersize + (18 * p_factor), 40 * p_factor, 16 * p_factor, Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, h_label); } /////////////////////////////////// draw the vertical ruler /////////////////////////////////////////// p_h = curve_h - bordersize - bordersize; p2_multiplier = 1; while(((max_value - min_value) * p2_multiplier) < 10000.0) { p2_multiplier *= 10; if(p2_multiplier > 10000000) { break; } } p2_ruler_startvalue = min_value * p2_multiplier; p2_ruler_endvalue = max_value * p2_multiplier; p2_range = p2_ruler_endvalue - p2_ruler_startvalue; if(p2_range < 0) p2_range *= -1; p2_pixels_per_unit = (double)p_h / (double)p2_range; p2_divisor = 1; while((p2_range / p2_divisor) > 10) { p2_divisor *= 2; if((p2_range / p2_divisor) <= 10) { break; } p2_divisor /= 2; p2_divisor *= 5; if((p2_range / p2_divisor) <= 10) { break; } p2_divisor *= 2; } if(drawVruler && (bordersize > (29 * p_factor))) { painter->drawLine(bordersize - (5 * p_factor), bordersize, bordersize - (5 * p_factor), curve_h - bordersize); precision = 0; if((max_value < 10.0) && (max_value > -10.0) && (min_value < 10.0) && (min_value > -10.0)) { precision = 1; if((max_value < 1.0) && (max_value > -1.0) && (min_value < 1.0) && (min_value > -1.0)) { precision = 2; if((max_value < 0.1) && (max_value > -0.1) && (min_value < 0.1) && (min_value > -0.1)) { precision = 3; if((max_value < 0.01) && (max_value > -0.01) && (min_value < 0.01) && (min_value > -0.01)) { precision = 4; } } } } for(i = (p2_ruler_startvalue / p2_divisor) * p2_divisor; i <= p2_ruler_endvalue; i += p2_divisor) { if(i < p2_ruler_startvalue) { continue; } q_str.setNum((double)i / (double)p2_multiplier, 'f', precision); p2_tmp = (double)(i - p2_ruler_startvalue) * p2_pixels_per_unit; if(curveUpSideDown == FALSE) { painter->drawText((3 * p_factor), curve_h - bordersize - p2_tmp - (8 * p_factor), (40 * p_factor), (16 * p_factor), Qt::AlignRight | Qt::AlignVCenter | Qt::TextSingleLine, q_str); painter->drawLine(bordersize - (5 * p_factor), curve_h - bordersize - p2_tmp, bordersize - (15 * p_factor), curve_h - bordersize - p2_tmp); } else { painter->drawText((3 * p_factor), bordersize + p2_tmp - (8 * p_factor), (40 * p_factor), (16 * p_factor), Qt::AlignRight | Qt::AlignVCenter | Qt::TextSingleLine, q_str); painter->drawLine(bordersize - (5 * p_factor), bordersize + p2_tmp, bordersize - (15 * p_factor), bordersize + p2_tmp); } } } /////////////////////////////////// draw the labels /////////////////////////////////////////// painter->setFont(curve_font); if(v_label[0] != 0) { painter->drawText(8 * p_factor, 30 * p_factor, 80 * p_factor, 16 * p_factor, Qt::AlignCenter | Qt::TextSingleLine, v_label); } if(upperlabel1[0] != 0) { painter->drawText(curve_w / 2 - (150 * p_factor), 10 * p_factor, 300 * p_factor, 16 * p_factor, Qt::AlignCenter | Qt::TextSingleLine, upperlabel1); } if(upperlabel2[0] != 0) { painter->drawText(curve_w / 2 - (150 * p_factor), 30 * p_factor, 300 * p_factor, 16 * p_factor, Qt::AlignCenter | Qt::TextSingleLine, upperlabel2); } if(lowerlabel[0] != 0) { painter->drawText(curve_w / 2 - (80 * p_factor), curve_h - (20 * p_factor), 160 * p_factor, 16 * p_factor, Qt::AlignCenter | Qt::TextSingleLine, lowerlabel); } /////////////////////////////////// translate coordinates, draw and fill a rectangle /////////////////////////////////////////// painter->translate(QPoint(bordersize, bordersize)); curve_w -= (bordersize * 2); curve_h -= (bordersize * 2); painter->setClipping(TRUE); painter->setClipRegion(QRegion(0, 0, curve_w, curve_h), Qt::ReplaceClip); /////////////////////////////////// draw the rasters /////////////////////////////////////////// painter->drawRect (0, 0, curve_w - 1, curve_h - 1); for(i = (p_ruler_startvalue / p_divisor) * p_divisor; i <= p_ruler_endvalue; i += p_divisor) { if(i < p_ruler_startvalue) { continue; } p_tmp = (double)(i - p_ruler_startvalue) * p_pixels_per_unit; painter->drawLine(p_tmp, 0, p_tmp, curve_h); } for(i = (p2_ruler_startvalue / p2_divisor) * p2_divisor; i <= p2_ruler_endvalue; i += p2_divisor) { if(i < p2_ruler_startvalue) { continue; } p2_tmp = (double)(i - p2_ruler_startvalue) * p2_pixels_per_unit; if(curveUpSideDown == FALSE) { painter->drawLine(0, curve_h - p2_tmp, curve_w, curve_h - p2_tmp); } else { painter->drawLine(0, p2_tmp, curve_w, p2_tmp); } } /////////////////////////////////// draw the curve /////////////////////////////////////////// if((dbuf == NULL) && (ibuf == NULL) && (fbuf == NULL)) return; if(max_value <= min_value) return; if(bufsize < 2) return; if(curveUpSideDown == TRUE) { offset = (-(min_value)); v_sens = curve_h / (max_value - min_value); } else { offset = (-(max_value)); v_sens = (-(curve_h / (max_value - min_value))); } h_step = (double)curve_w / (double)bufsize; if(dbuf) { for(i = 0; i < bufsize; i++) { if(fillsurface) { if(bufsize < curve_w) { for(j = 0; j < h_step; j++) { painter->drawLine((i * h_step) + j, (dbuf[i] + offset) * v_sens, (i * h_step) + j, curve_h); } } else { painter->drawLine(i * h_step, (dbuf[i] + offset) * v_sens, i * h_step, curve_h); } } else { if(bufsize < (curve_w / 2)) { painter->drawLine(i * h_step, (dbuf[i] + offset) * v_sens, (i + 1) * h_step, (dbuf[i] + offset) * v_sens); if(i) { painter->drawLine(i * h_step, (dbuf[i - 1] + offset) * v_sens, i * h_step, (dbuf[i] + offset) * v_sens); } } else { if(i < (bufsize - 1)) { { painter->drawLine(i * h_step, (dbuf[i] + offset) * v_sens, (i + 1) * h_step, (dbuf[i + 1] + offset) * v_sens); } } } } if(crosshair_1_active) { if(i==((int)(((double)crosshair_1_x_position * p_factor) / h_step))) { crosshair_1_y_value = (dbuf[i] + offset) * v_sens; crosshair_1_value = dbuf[i]; value = (h_ruler_endvalue - h_ruler_startvalue) / bufsize; crosshair_1_value_2 = (i * value) + (0.5 * value) + h_ruler_startvalue; } } } } if(ibuf) { for(i = 0; i < bufsize; i++) { if(fillsurface) { if(bufsize < curve_w) { for(j = 0; j < h_step; j++) { painter->drawLine((i * h_step) + j, ((double)(ibuf[i]) + offset) * v_sens, (i * h_step) + j, curve_h); } } else { painter->drawLine(i * h_step, ((double)(ibuf[i]) + offset) * v_sens, i * h_step, curve_h); } } else { if(bufsize < (curve_w / 2)) { painter->drawLine(i * h_step, ((double)(ibuf[i]) + offset) * v_sens, (i + 1) * h_step, ((double)(ibuf[i]) + offset) * v_sens); if(i) { painter->drawLine(i * h_step, ((double)(ibuf[i - 1]) + offset) * v_sens, i * h_step, ((double)(ibuf[i]) + offset) * v_sens); } } else { if(i < (bufsize - 1)) { { painter->drawLine(i * h_step, ((double)(ibuf[i]) + offset) * v_sens, (i + 1) * h_step, ((double)(ibuf[i + 1]) + offset) * v_sens); } } } } if(crosshair_1_active) { if(i==((int)(((double)crosshair_1_x_position * p_factor) / h_step))) { crosshair_1_y_value = ((double)(ibuf[i]) + offset) * v_sens; crosshair_1_value = (double)(ibuf[i]); value = (h_ruler_endvalue - h_ruler_startvalue) / bufsize; crosshair_1_value_2 = (i * value) + (0.5 * value) + h_ruler_startvalue; } } } } if(fbuf) { for(i = 0; i < bufsize; i++) { if(fillsurface) { if(bufsize < curve_w) { for(j = 0; j < h_step; j++) { painter->drawLine((i * h_step) + j, (fbuf[i] + offset) * v_sens, (i * h_step) + j, curve_h); } } else { painter->drawLine(i * h_step, (fbuf[i] + offset) * v_sens, i * h_step, curve_h); } } else { if(bufsize < (curve_w / 2)) { painter->drawLine(i * h_step, (fbuf[i] + offset) * v_sens, (i + 1) * h_step, (fbuf[i] + offset) * v_sens); if(i) { painter->drawLine(i * h_step, (fbuf[i - 1] + offset) * v_sens, i * h_step, (fbuf[i] + offset) * v_sens); } } else { if(i < (bufsize - 1)) { { painter->drawLine(i * h_step, (fbuf[i] + offset) * v_sens, (i + 1) * h_step, (fbuf[i + 1] + offset) * v_sens); } } } } if(crosshair_1_active) { if(i==((int)(((double)crosshair_1_x_position * p_factor) / h_step))) { crosshair_1_y_value = (fbuf[i] + offset) * v_sens; crosshair_1_value = fbuf[i]; value = (h_ruler_endvalue - h_ruler_startvalue) / bufsize; crosshair_1_value_2 = (i * value) + (0.5 * value) + h_ruler_startvalue; } } } } /////////////////////////////////// draw the line /////////////////////////////////////////// if(line1Enabled == TRUE) { painter->drawLine(line1_start_x * h_step, (line1_start_y + offset) * v_sens, line1_end_x * h_step, (line1_end_y + offset) * v_sens); } /////////////////////////////////// draw the markers /////////////////////////////////////////// if(Marker1Enabled == TRUE) { painter->drawLine(curve_w * marker_1_position, 0, curve_w * marker_1_position, curve_h); } if(Marker2Enabled == TRUE) { painter->drawLine(curve_w * marker_2_position, 0, curve_w * marker_2_position, curve_h); } /////////////////////////////////// draw the cursor /////////////////////////////////////////// if(crosshair_1_active) { QPainterPath path; path.moveTo(crosshair_1_x_position * p_factor, crosshair_1_y_value); path.lineTo((crosshair_1_x_position - 4) * p_factor, crosshair_1_y_value - (9 * p_factor)); path.lineTo((crosshair_1_x_position + 4) * p_factor, crosshair_1_y_value - (9 * p_factor)); path.lineTo(crosshair_1_x_position * p_factor, crosshair_1_y_value); painter->fillPath(path, QBrush(Qt::black)); snprintf(str, 128, "%f", crosshair_1_value); painter->drawText((crosshair_1_x_position + 8) * p_factor, (crosshair_1_y_position - 10) * p_factor, str); snprintf(str, 128, "%f %s", crosshair_1_value_2, h_label); painter->drawText((crosshair_1_x_position + 8) * p_factor, (crosshair_1_y_position + 10) * p_factor, str); } bordersize = bordersize_backup; } void SignalCurve::setUpdatesEnabled(bool enabled) { updates_enabled = enabled; } void SignalCurve::paintEvent(QPaintEvent *) { if(updates_enabled == TRUE) { QPainter paint(this); drawWidget(&paint, width(), height()); old_w = width(); } } void SignalCurve::drawWidget(QPainter *painter, int curve_w, int curve_h) { int i, j, precision, p_w, p_divisor, p_range, p_multiplier, p_ruler_startvalue, p_ruler_endvalue, p_tmp, p_h, p2_divisor, p2_range, p2_multiplier, p2_ruler_startvalue, p2_ruler_endvalue, p2_tmp; double v_sens=0.0, offset=0.0, h_step=0.0, value, pixelsPerUnit, max_colorbar_value, p_pixels_per_unit, p2_pixels_per_unit; char str[128]; QString q_str; painter->setFont(QFont("Arial", 8)); painter->fillRect(0, 0, curve_w, curve_h, BorderColor); if((curve_w < ((bordersize * 2) + 5)) || (curve_h < ((bordersize * 2) + 5))) { return; } /////////////////////////////////// draw the horizontal ruler /////////////////////////////////////////// p_w = curve_w - bordersize - bordersize; p_multiplier = 1; while((h_ruler_endvalue * p_multiplier) < 10000.0) { p_multiplier *= 10; if(p_multiplier > 10000000) { break; } } p_ruler_startvalue = h_ruler_startvalue * p_multiplier; p_ruler_endvalue = h_ruler_endvalue * p_multiplier; p_range = p_ruler_endvalue - p_ruler_startvalue; p_pixels_per_unit = (double)p_w / (double)p_range; p_divisor = 1; while((p_range / p_divisor) > 10) { p_divisor *= 2; if((p_range / p_divisor) <= 10) { break; } p_divisor /= 2; p_divisor *= 5; if((p_range / p_divisor) <= 10) { break; } p_divisor *= 2; } // printf("p_multiplier is %i\n" // "p_ruler_startvalue is %i\n" // "p_ruler_endvalue is %i\n" // "p_range is %i\n" // "p_divisor is %i\n" // "p_pixels_per_unit is %f\n\n", // p_multiplier, // p_ruler_startvalue, // p_ruler_endvalue, // p_range, // p_divisor, // p_pixels_per_unit); if(drawHruler && (bordersize > 19)) { painter->setPen(RulerColor); painter->drawLine(bordersize, curve_h - bordersize + 5, curve_w - bordersize, curve_h - bordersize + 5); h_ruler_precision = 0; if((h_ruler_endvalue < 10.0) && (h_ruler_endvalue > -10.0) && (h_ruler_startvalue < 10.0) && (h_ruler_startvalue > -10.0)) { h_ruler_precision = 1; if((h_ruler_endvalue < 1.0) && (h_ruler_endvalue > -1.0) && (h_ruler_startvalue < 1.0) && (h_ruler_startvalue > -1.0)) { h_ruler_precision = 2; if((h_ruler_endvalue < 0.1) && (h_ruler_endvalue > -0.1) && (h_ruler_startvalue < 0.1) && (h_ruler_startvalue > -0.1)) { h_ruler_precision = 3; if((h_ruler_endvalue < 0.01) && (h_ruler_endvalue > -0.01) && (h_ruler_startvalue < 0.01) && (h_ruler_startvalue > -0.01)) { h_ruler_precision = 4; } } } } for(i = (p_ruler_startvalue / p_divisor) * p_divisor; i <= p_ruler_endvalue; i += p_divisor) { if(i < p_ruler_startvalue) { continue; } q_str.setNum((double)i / (double)p_multiplier, 'f', h_ruler_precision); p_tmp = (double)(i - p_ruler_startvalue) * p_pixels_per_unit; painter->drawText(bordersize + p_tmp - 30, curve_h - bordersize + 18, 60, 16, Qt::AlignCenter | Qt::TextSingleLine, q_str); painter->drawLine(bordersize + p_tmp, curve_h - bordersize + 5, bordersize + p_tmp, curve_h - bordersize + 5 + 10); } painter->drawText(curve_w - bordersize + 20, curve_h - bordersize + 18, 40, 16, Qt::AlignLeft | Qt::AlignVCenter | Qt::TextSingleLine, h_label); } /////////////////////////////////// draw the vertical ruler /////////////////////////////////////////// p_h = curve_h - bordersize - bordersize; p2_multiplier = 1; while(((max_value - min_value) * p2_multiplier) < 10000.0) { p2_multiplier *= 10; if(p2_multiplier > 10000000) { break; } } p2_ruler_startvalue = min_value * p2_multiplier; p2_ruler_endvalue = max_value * p2_multiplier; p2_range = p2_ruler_endvalue - p2_ruler_startvalue; if(p2_range < 0) p2_range *= -1; p2_pixels_per_unit = (double)p_h / (double)p2_range; p2_divisor = 1; while((p2_range / p2_divisor) > 10) { p2_divisor *= 2; if((p2_range / p2_divisor) <= 10) { break; } p2_divisor /= 2; p2_divisor *= 5; if((p2_range / p2_divisor) <= 10) { break; } p2_divisor *= 2; } // printf("p2_multiplier is %i\n" // "p2_ruler_startvalue is %i\n" // "p2_ruler_endvalue is %i\n" // "p2_range is %i\n" // "p2_divisor is %i\n" // "p2_pixels_per_unit is %f\n" // "max_value is %f\n" // "min_value is %f\n\n", // p2_multiplier, // p2_ruler_startvalue, // p2_ruler_endvalue, // p2_range, // p2_divisor, // p2_pixels_per_unit, // max_value, // min_value); if(drawVruler && (bordersize > 29)) { painter->setPen(RulerColor); painter->drawLine(bordersize - 5, bordersize, bordersize - 5, curve_h - bordersize); precision = 0; if((max_value < 10.0) && (max_value > -10.0) && (min_value < 10.0) && (min_value > -10.0)) { precision = 1; if((max_value < 1.0) && (max_value > -1.0) && (min_value < 1.0) && (min_value > -1.0)) { precision = 2; if((max_value < 0.1) && (max_value > -0.1) && (min_value < 0.1) && (min_value > -0.1)) { precision = 3; if((max_value < 0.01) && (max_value > -0.01) && (min_value < 0.01) && (min_value > -0.01)) { precision = 4; } } } } for(i = (p2_ruler_startvalue / p2_divisor) * p2_divisor; i <= p2_ruler_endvalue; i += p2_divisor) { if(i < p2_ruler_startvalue) { continue; } q_str.setNum((double)i / (double)p2_multiplier, 'f', precision); p2_tmp = (double)(i - p2_ruler_startvalue) * p2_pixels_per_unit; if(curveUpSideDown == FALSE) { painter->drawText(3, curve_h - bordersize - p2_tmp - 8, 40, 16, Qt::AlignRight | Qt::AlignVCenter | Qt::TextSingleLine, q_str); painter->drawLine(bordersize - 5, curve_h - bordersize - p2_tmp, bordersize - 5 - 10, curve_h - bordersize - p2_tmp); } else { painter->drawText(3, bordersize + p2_tmp - 8, 40, 16, Qt::AlignRight | Qt::AlignVCenter | Qt::TextSingleLine, q_str); painter->drawLine(bordersize - 5, bordersize + p2_tmp, bordersize - 5 - 10, bordersize + p2_tmp); } } } /////////////////////////////////// draw the labels /////////////////////////////////////////// painter->setPen(TextColor); painter->setFont(QFont("Arial", 8)); if(v_label[0] != 0) { painter->drawText(8, 30, 80, 16, Qt::AlignCenter | Qt::TextSingleLine, v_label); } if(upperlabel1[0] != 0) { painter->drawText(curve_w / 2 - 150, 20, 300, 16, Qt::AlignCenter | Qt::TextSingleLine, upperlabel1); } if(lowerlabel[0] != 0) { painter->drawText(curve_w / 2 - 80, curve_h - 20, 160, 16, Qt::AlignCenter | Qt::TextSingleLine, lowerlabel); } /////////////////////////////////// translate coordinates, draw and fill a rectangle /////////////////////////////////////////// painter->translate(QPoint(bordersize, bordersize)); curve_w -= (bordersize * 2); curve_h -= (bordersize * 2); painter->fillRect(0, 0, curve_w, curve_h, BackgroundColor); painter->setClipping(TRUE); painter->setClipRegion(QRegion(0, 0, curve_w, curve_h), Qt::ReplaceClip); /////////////////////////////////// draw the colorbars ///////////////////////////////////////// if(spectrum_color != NULL) { max_colorbar_value = 0.0; for(i=0; i < spectrum_color->items; i++) { if(spectrum_color->value[i] > max_colorbar_value) { max_colorbar_value = spectrum_color->value[i]; } } max_colorbar_value *= 1.05; pixelsPerUnit = (double)curve_w / (h_ruler_endvalue - h_ruler_startvalue); if((spectrum_color->freq[0] > h_ruler_startvalue) && (spectrum_color->items > 1)) { painter->fillRect(0, (max_colorbar_value - spectrum_color->value[0]) * ((double)curve_h / max_colorbar_value), (spectrum_color->freq[0] - h_ruler_startvalue) * pixelsPerUnit, curve_h, (Qt::GlobalColor)spectrum_color->color[0]); painter->setPen(Qt::lightGray); painter->drawText(10, 20, spectrum_color->label[0]); } for(i=1; i < spectrum_color->items; i++) { if(spectrum_color->freq[i] > h_ruler_startvalue) { painter->fillRect((spectrum_color->freq[i-1] - h_ruler_startvalue) * pixelsPerUnit, (max_colorbar_value - spectrum_color->value[i]) * ((double)curve_h / max_colorbar_value), (spectrum_color->freq[i] - spectrum_color->freq[i-1]) * pixelsPerUnit, curve_h, (Qt::GlobalColor)spectrum_color->color[i]); painter->setPen(Qt::lightGray); painter->drawText((spectrum_color->freq[i-1] - h_ruler_startvalue) * pixelsPerUnit + 10, 20, spectrum_color->label[i]); } } } /////////////////////////////////// draw the curve /////////////////////////////////////////// if(drawcurve_before_raster) { if((dbuf == NULL) && (ibuf == NULL) && (fbuf == NULL)) return; if(max_value <= min_value) return; if(bufsize < 2) return; if(curveUpSideDown == TRUE) { offset = (-(min_value)); v_sens = curve_h / (max_value - min_value); } else { offset = (-(max_value)); v_sens = (-(curve_h / (max_value - min_value))); } h_step = (double)curve_w / (double)bufsize; painter->setPen(QPen(QBrush(SignalColor, Qt::SolidPattern), tracewidth, Qt::SolidLine, Qt::SquareCap, Qt::BevelJoin)); if(dbuf) { for(i = 0; i < bufsize; i++) { if(fillsurface) { if(bufsize < curve_w) { for(j = 0; j < h_step; j++) { painter->drawLine((i * h_step) + j, (dbuf[i] + offset) * v_sens, (i * h_step) + j, curve_h); } } else { painter->drawLine(i * h_step, (dbuf[i] + offset) * v_sens, i * h_step, curve_h); } } else { if(bufsize < (curve_w / 2)) { painter->drawLine(i * h_step, (dbuf[i] + offset) * v_sens, (i + 1) * h_step, (dbuf[i] + offset) * v_sens); if(i) { painter->drawLine(i * h_step, (dbuf[i - 1] + offset) * v_sens, i * h_step, (dbuf[i] + offset) * v_sens); } } else { if(i < (bufsize - 1)) { { painter->drawLine(i * h_step, (dbuf[i] + offset) * v_sens, (i + 1) * h_step, (dbuf[i + 1] + offset) * v_sens); } } } } if(crosshair_1_active) { if(i==((int)(((double)crosshair_1_x_position) / h_step))) { crosshair_1_y_value = (dbuf[i] + offset) * v_sens; crosshair_1_value = dbuf[i]; value = (h_ruler_endvalue - h_ruler_startvalue) / bufsize; crosshair_1_value_2 = (i * value) + h_ruler_startvalue; } } } } if(ibuf) { for(i = 0; i < bufsize; i++) { if(fillsurface) { if(bufsize < curve_w) { for(j = 0; j < h_step; j++) { painter->drawLine((i * h_step) + j, ((double)(ibuf[i]) + offset) * v_sens, (i * h_step) + j, curve_h); } } else { painter->drawLine(i * h_step, ((double)(ibuf[i]) + offset) * v_sens, i * h_step, curve_h); } } else { if(bufsize < (curve_w / 2)) { painter->drawLine(i * h_step, ((double)(ibuf[i]) + offset) * v_sens, (i + 1) * h_step, ((double)(ibuf[i]) + offset) * v_sens); if(i) { painter->drawLine(i * h_step, ((double)(ibuf[i - 1]) + offset) * v_sens, i * h_step, ((double)(ibuf[i]) + offset) * v_sens); } } else { if(i < (bufsize - 1)) { { painter->drawLine(i * h_step, ((double)(ibuf[i]) + offset) * v_sens, (i + 1) * h_step, ((double)(ibuf[i + 1]) + offset) * v_sens); } } } } if(crosshair_1_active) { if(i==((int)(((double)crosshair_1_x_position) / h_step))) { crosshair_1_y_value = ((double)(ibuf[i]) + offset) * v_sens; crosshair_1_value = (double)(ibuf[i]); value = (h_ruler_endvalue - h_ruler_startvalue) / bufsize; crosshair_1_value_2 = (i * value) + h_ruler_startvalue; } } } } if(fbuf) { for(i = 0; i < bufsize; i++) { if(fillsurface) { if(bufsize < curve_w) { for(j = 0; j < h_step; j++) { painter->drawLine((i * h_step) + j, (fbuf[i] + offset) * v_sens, (i * h_step) + j, curve_h); } } else { painter->drawLine(i * h_step, (fbuf[i] + offset) * v_sens, i * h_step, curve_h); } } else { if(bufsize < (curve_w / 2)) { painter->drawLine(i * h_step, (fbuf[i] + offset) * v_sens, (i + 1) * h_step, (fbuf[i] + offset) * v_sens); if(i) { painter->drawLine(i * h_step, (fbuf[i - 1] + offset) * v_sens, i * h_step, (fbuf[i] + offset) * v_sens); } } else { if(i < (bufsize - 1)) { { painter->drawLine(i * h_step, (fbuf[i] + offset) * v_sens, (i + 1) * h_step, (fbuf[i + 1] + offset) * v_sens); } } } } if(crosshair_1_active) { if(i==((int)(((double)crosshair_1_x_position) / h_step))) { crosshair_1_y_value = (fbuf[i] + offset) * v_sens; crosshair_1_value = fbuf[i]; value = (h_ruler_endvalue - h_ruler_startvalue) / bufsize; crosshair_1_value_2 = (i * value) + h_ruler_startvalue; } } } } } /////////////////////////////////// draw the rasters /////////////////////////////////////////// painter->setPen(RasterColor); painter->drawRect (0, 0, curve_w - 1, curve_h - 1); for(i = (p_ruler_startvalue / p_divisor) * p_divisor; i <= p_ruler_endvalue; i += p_divisor) { if(i < p_ruler_startvalue) { continue; } p_tmp = (double)(i - p_ruler_startvalue) * p_pixels_per_unit; painter->drawLine(p_tmp, 0, p_tmp, curve_h); } for(i = (p2_ruler_startvalue / p2_divisor) * p2_divisor; i <= p2_ruler_endvalue; i += p2_divisor) { if(i < p2_ruler_startvalue) { continue; } p2_tmp = (double)(i - p2_ruler_startvalue) * p2_pixels_per_unit; if(curveUpSideDown == FALSE) { painter->drawLine(0, curve_h - p2_tmp, curve_w, curve_h - p2_tmp); } else { painter->drawLine(0, p2_tmp, curve_w, p2_tmp); } } /////////////////////////////////// draw the curve /////////////////////////////////////////// if(!drawcurve_before_raster) { if((dbuf == NULL) && (ibuf == NULL) && (fbuf == NULL)) return; if(max_value <= min_value) return; if(bufsize < 2) return; if(curveUpSideDown == TRUE) { offset = (-(min_value)); v_sens = curve_h / (max_value - min_value); } else { offset = (-(max_value)); v_sens = (-(curve_h / (max_value - min_value))); } h_step = (double)curve_w / (double)bufsize; painter->setPen(QPen(QBrush(SignalColor, Qt::SolidPattern), tracewidth, Qt::SolidLine, Qt::SquareCap, Qt::BevelJoin)); if(dbuf) { for(i = 0; i < bufsize; i++) { if(fillsurface) { if(bufsize < curve_w) { for(j = 0; j < h_step; j++) { painter->drawLine((i * h_step) + j, (dbuf[i] + offset) * v_sens, (i * h_step) + j, curve_h); } } else { painter->drawLine(i * h_step, (dbuf[i] + offset) * v_sens, i * h_step, curve_h); } } else { if(bufsize < (curve_w / 2)) { painter->drawLine(i * h_step, (dbuf[i] + offset) * v_sens, (i + 1) * h_step, (dbuf[i] + offset) * v_sens); if(i) { painter->drawLine(i * h_step, (dbuf[i - 1] + offset) * v_sens, i * h_step, (dbuf[i] + offset) * v_sens); } } else { if(i < (bufsize - 1)) { painter->drawLine(i * h_step, (dbuf[i] + offset) * v_sens, (i + 1) * h_step, (dbuf[i + 1] + offset) * v_sens); } } } if(crosshair_1_active) { if(i==((int)(((double)crosshair_1_x_position) / h_step))) { crosshair_1_y_value = (dbuf[i] + offset) * v_sens; crosshair_1_value = dbuf[i]; value = (h_ruler_endvalue - h_ruler_startvalue) / bufsize; crosshair_1_value_2 = (i * value) + h_ruler_startvalue; } } } } if(ibuf) { for(i = 0; i < bufsize; i++) { if(fillsurface) { if(bufsize < curve_w) { for(j = 0; j < h_step; j++) { painter->drawLine((i * h_step) + j, ((double)(ibuf[i]) + offset) * v_sens, (i * h_step) + j, curve_h); } } else { painter->drawLine(i * h_step, ((double)(ibuf[i]) + offset) * v_sens, i * h_step, curve_h); } } else { if(bufsize < (curve_w / 2)) { painter->drawLine(i * h_step, ((double)(ibuf[i]) + offset) * v_sens, (i + 1) * h_step, ((double)(ibuf[i]) + offset) * v_sens); if(i) { painter->drawLine(i * h_step, ((double)(ibuf[i - 1]) + offset) * v_sens, i * h_step, ((double)(ibuf[i]) + offset) * v_sens); } } else { if(i < (bufsize - 1)) { { painter->drawLine(i * h_step, ((double)(ibuf[i]) + offset) * v_sens, (i + 1) * h_step, ((double)(ibuf[i + 1]) + offset) * v_sens); } } } } if(crosshair_1_active) { if(i==((int)(((double)crosshair_1_x_position) / h_step))) { crosshair_1_y_value = ((double)(ibuf[i]) + offset) * v_sens; crosshair_1_value = (double)(ibuf[i]); value = (h_ruler_endvalue - h_ruler_startvalue) / bufsize; crosshair_1_value_2 = (i * value) + h_ruler_startvalue; } } } } if(fbuf) { for(i = 0; i < bufsize; i++) { if(fillsurface) { if(bufsize < curve_w) { for(j = 0; j < h_step; j++) { painter->drawLine((i * h_step) + j, (fbuf[i] + offset) * v_sens, (i * h_step) + j, curve_h); } } else { painter->drawLine(i * h_step, (fbuf[i] + offset) * v_sens, i * h_step, curve_h); } } else { if(bufsize < (curve_w / 2)) { painter->drawLine(i * h_step, (fbuf[i] + offset) * v_sens, (i + 1) * h_step, (fbuf[i] + offset) * v_sens); if(i) { painter->drawLine(i * h_step, (fbuf[i - 1] + offset) * v_sens, i * h_step, (fbuf[i] + offset) * v_sens); } } else { if(i < (bufsize - 1)) { { painter->drawLine(i * h_step, (fbuf[i] + offset) * v_sens, (i + 1) * h_step, (fbuf[i + 1] + offset) * v_sens); } } } } if(crosshair_1_active) { if(i==((int)(((double)crosshair_1_x_position) / h_step))) { crosshair_1_y_value = (fbuf[i] + offset) * v_sens; crosshair_1_value = fbuf[i]; value = (h_ruler_endvalue - h_ruler_startvalue) / bufsize; crosshair_1_value_2 = (i * value) + h_ruler_startvalue; } } } } } /////////////////////////////////// draw the line /////////////////////////////////////////// if(line1Enabled == TRUE) { painter->setPen(QPen(QBrush(line1Color, Qt::SolidPattern), tracewidth, Qt::SolidLine, Qt::SquareCap, Qt::BevelJoin)); painter->drawLine(line1_start_x * h_step, (line1_start_y + offset) * v_sens, line1_end_x * h_step, (line1_end_y + offset) * v_sens); } /////////////////////////////////// draw the markers /////////////////////////////////////////// if(Marker1Enabled == TRUE) { painter->setPen(Marker1Pen); painter->drawLine(curve_w * marker_1_position, 0, curve_w * marker_1_position, curve_h); } if(Marker2Enabled == TRUE) { painter->setPen(Marker2Pen); painter->drawLine(curve_w * marker_2_position, 0, curve_w * marker_2_position, curve_h); } /////////////////////////////////// draw the cursor /////////////////////////////////////////// if(crosshair_1_active) { painter->setPen(crosshair_1_color); QPainterPath path; path.moveTo(crosshair_1_x_position, crosshair_1_y_value); path.lineTo(crosshair_1_x_position - 4, crosshair_1_y_value - 10); path.lineTo(crosshair_1_x_position + 5, crosshair_1_y_value - 10); path.lineTo(crosshair_1_x_position, crosshair_1_y_value); painter->fillPath(path, QBrush(crosshair_1_color)); painter->setFont(QFont("Arial", 10)); painter->fillRect(crosshair_1_x_position + 6, crosshair_1_y_position - 23, 60, 16, BackgroundColor); snprintf(str, 128, "%f", crosshair_1_value); painter->drawText(crosshair_1_x_position + 8, crosshair_1_y_position - 10, str); painter->fillRect(crosshair_1_x_position + 6, crosshair_1_y_position - 3, 60, 16, BackgroundColor); snprintf(str, 128, "%f %s", crosshair_1_value_2, h_label); painter->drawText(crosshair_1_x_position + 8, crosshair_1_y_position + 10, str); } /////////////////////////////////// draw the buttons /////////////////////////////////////////// painter->setPen(Qt::black); painter->setFont(QFont("Arial", 8)); if(printEnabled == TRUE) { painter->fillRect(curve_w - 43, 3, 40, 18, Qt::gray); painter->drawText(curve_w - 38, 16, "print"); } if(cursorEnabled == TRUE) { painter->fillRect(curve_w - 43, 23, 40, 18, Qt::gray); painter->drawText(curve_w - 38, 36, "cursor"); } if(dashBoardEnabled == TRUE) { painter->fillRect(curve_w - 43, 43, 40, 18, Qt::gray); painter->drawText(curve_w - 38, 56, "ctls"); } } void SignalCurve::drawLine(int start_x, double start_y, int end_x, double end_y, QColor lineColor) { line1Color = lineColor; line1_start_x = start_x; if(line1_start_x < 0) { line1_start_x = 0; } if(line1_start_x >= bufsize) { line1_start_x = bufsize - 1; } line1_start_y = start_y; line1_end_x = end_x; if(line1_end_x < 0) { line1_end_x = 0; } if(line1_end_x >= bufsize) { line1_end_x = bufsize - 1; } line1_end_y = end_y; line1Enabled = TRUE; update(); } void SignalCurve::setLineEnabled(bool stat) { line1Enabled = stat; update(); } void SignalCurve::drawCurve(double *samplebuf, int bsize, double max_val, double min_val) { dbuf = samplebuf; ibuf = NULL; fbuf = NULL; bufsize = bsize; max_value = max_val; min_value = min_val; update(); } void SignalCurve::drawCurve(int *samplebuf, int bsize, double max_val, double min_val) { ibuf = samplebuf; dbuf = NULL; fbuf = NULL; bufsize = bsize; max_value = max_val; min_value = min_val; update(); } void SignalCurve::drawCurve(float *samplebuf, int bsize, double max_val, double min_val) { fbuf = samplebuf; dbuf = NULL; ibuf = NULL; bufsize = bsize; max_value = max_val; min_value = min_val; update(); } void SignalCurve::setFillSurfaceEnabled(bool enabled) { if(enabled == TRUE) { fillsurface = 1; } else { fillsurface = 0; } update(); } void SignalCurve::setMarker1Position(double mrk_pos) { marker_1_position = mrk_pos; if(marker_1_position > 1.01) marker_1_position = 1.01; if(marker_1_position < 0.0001) marker_1_position = 0.0001; update(); } void SignalCurve::setMarker1Enabled(bool on) { Marker1Enabled = on; update(); } void SignalCurve::setMarker1MovableEnabled(bool on) { Marker1MovableEnabled = on; update(); } void SignalCurve::setMarker1Color(QColor color) { Marker1Pen.setColor(color); update(); } double SignalCurve::getMarker1Position(void) { return(marker_1_position); } void SignalCurve::setMarker2Position(double mrk_pos) { marker_2_position = mrk_pos; if(marker_2_position > 1.01) marker_2_position = 1.01; if(marker_2_position < 0.0001) marker_2_position = 0.0001; update(); } void SignalCurve::setMarker2Enabled(bool on) { Marker2Enabled = on; update(); } void SignalCurve::setMarker2MovableEnabled(bool on) { Marker2MovableEnabled = on; update(); } void SignalCurve::setMarker2Color(QColor color) { Marker2Pen.setColor(color); update(); } double SignalCurve::getMarker2Position(void) { return(marker_2_position); } void SignalCurve::setH_RulerValues(double start, double end) { h_ruler_startvalue = start; h_ruler_endvalue = end; update(); } void SignalCurve::setSignalColor(QColor newColor) { SignalColor = newColor; update(); } void SignalCurve::setCrosshairColor(QColor newColor) { crosshair_1_color = newColor; update(); } void SignalCurve::setTraceWidth(int tr_width) { tracewidth = tr_width; if(tracewidth < 0) tracewidth = 0; update(); } void SignalCurve::setBackgroundColor(QColor newColor) { BackgroundColor = newColor; update(); } void SignalCurve::setRasterColor(QColor newColor) { RasterColor = newColor; update(); } void SignalCurve::setBorderColor(QColor newColor) { BorderColor = newColor; update(); } void SignalCurve::setTextColor(QColor newColor) { TextColor = newColor; update(); } void SignalCurve::setBorderSize(int newsize) { bordersize = newsize; if(bordersize < 0) bordersize = 0; update(); } void SignalCurve::setH_label(const char *str) { strncpy(h_label, str, 32); h_label[31] = 0; update(); } void SignalCurve::setV_label(const char *str) { strncpy(v_label, str, 15); v_label[15] = 0; update(); } void SignalCurve::setUpperLabel1(const char *str) { strncpy(upperlabel1, str, 64); upperlabel1[63] = 0; update(); } void SignalCurve::setUpperLabel2(const char *str) { strncpy(upperlabel2, str, 64); upperlabel2[63] = 0; update(); } void SignalCurve::setLowerLabel(const char *str) { strncpy(lowerlabel, str, 64); lowerlabel[63] = 0; update(); } void SignalCurve::setCursorEnabled(bool value) { cursorEnabled = value; } bool SignalCurve::isCursorEnabled(void) { return(cursorEnabled); } bool SignalCurve::isCursorActive(void) { return(crosshair_1_active); } void SignalCurve::setPrintEnabled(bool value) { printEnabled = value; } void SignalCurve::setDashBoardEnabled(bool value) { dashBoardEnabled = value; } void SignalCurve::enableSpectrumColors(struct spectrum_markersblock *spectr_col) { spectrum_color = spectr_col; update(); } void SignalCurve::disableSpectrumColors() { spectrum_color = NULL; update(); } void SignalCurve::setV_rulerEnabled(bool value) { if(value == TRUE) { drawVruler = 1; } else { drawVruler = 0; } } void SignalCurve::setUpsidedownEnabled(bool value) { curveUpSideDown = value; } int SignalCurve::getCursorPosition(void) { return(crosshair_1_value_2); } /* size is size of destination, returns length of directory */ /* last character of destination is not a slash! */ int SignalCurve::get_directory_from_path(char *dest, const char *src, int ssize) { int i, len; if(ssize<1) { return(-1); } if(ssize<2) { dest[0] = 0; return(0); } len = strlen(src); if(len < 1) { dest[0] = 0; return(0); } for(i=len-1; i>=0; i--) { if((src[i]=='/') || (src[i]=='\\')) { break; } } strncpy(dest, src, ssize); if(i < ssize) { dest[i] = 0; } else { dest[ssize-1] = 0; } return(strlen(dest)); } edfbrowser_153_source/PaxHeaders.2978/raw2edf.cpp0000644000175000001440000000013212251654530020205 xustar000000000000000030 mtime=1386699096.478032517 30 atime=1386699096.478032517 30 ctime=1386699096.478032517 edfbrowser_153_source/raw2edf.cpp0000644000175000001440000006565412251654530017756 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "raw2edf.h" #if defined(__APPLE__) || defined(__MACH__) || defined(__APPLE_CC__) #define fopeno fopen #else #define fseeko fseeko64 #define ftello ftello64 #define fopeno fopen64 #endif UI_RAW2EDFapp::UI_RAW2EDFapp(struct raw2edf_var_struct *raw2edf_var_p, char *recent_dir, char *save_dir) { recent_opendir = recent_dir; recent_savedir = save_dir; raw2edf_var = raw2edf_var_p; edf_format = 1; raw2edfDialog = new QDialog; raw2edfDialog->setMinimumSize(600, 480); raw2edfDialog->setMaximumSize(600, 480); raw2edfDialog->setWindowTitle("Binary/raw data to EDF converter"); raw2edfDialog->setModal(TRUE); raw2edfDialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); SamplefreqLabel = new QLabel(raw2edfDialog); SamplefreqLabel->setGeometry(20, 20, 140, 20); SamplefreqLabel->setText("Samplefrequency"); SamplefreqSpinbox = new QSpinBox(raw2edfDialog); SamplefreqSpinbox->setGeometry(160, 20, 120, 20); SamplefreqSpinbox->setRange(1,1000000); SamplefreqSpinbox->setSuffix(" Hz"); SamplefreqSpinbox->setValue(raw2edf_var->sf); SamplefreqSpinbox->setToolTip("Samplerate"); SignalsLabel = new QLabel(raw2edfDialog); SignalsLabel->setGeometry(20, 60, 140, 20); SignalsLabel->setText("Number of signals"); SignalsSpinbox = new QSpinBox(raw2edfDialog); SignalsSpinbox->setGeometry(160, 60, 120, 20); SignalsSpinbox->setRange(1,256); SignalsSpinbox->setValue(raw2edf_var->chns); SignalsSpinbox->setToolTip("Number of channels"); SampleSizeLabel = new QLabel(raw2edfDialog); SampleSizeLabel->setGeometry(20, 100, 140, 20); SampleSizeLabel->setText("Sample size"); SampleSizeSpinbox = new QSpinBox(raw2edfDialog); SampleSizeSpinbox->setGeometry(160, 100, 120, 20); SampleSizeSpinbox->setRange(1,2); SampleSizeSpinbox->setValue(raw2edf_var->samplesize); SampleSizeSpinbox->setSuffix(" byte(s)"); SampleSizeSpinbox->setToolTip("Bytes per sample"); OffsetLabel = new QLabel(raw2edfDialog); OffsetLabel->setGeometry(20, 140, 140, 20); OffsetLabel->setText("Offset"); OffsetSpinbox = new QSpinBox(raw2edfDialog); OffsetSpinbox->setGeometry(160, 140, 120, 20); OffsetSpinbox->setRange(0,1000000); OffsetSpinbox->setValue(raw2edf_var->offset); OffsetSpinbox->setToolTip("Bytes to skip from start of file to data startpoint"); EncodingLabel = new QLabel(raw2edfDialog); EncodingLabel->setGeometry(20, 180, 140, 20); EncodingLabel->setText("Encoding"); EncodingCombobox = new QComboBox(raw2edfDialog); EncodingCombobox->setGeometry(160, 180, 120, 20); EncodingCombobox->addItem("2's complement"); EncodingCombobox->addItem("bipolar offset binary"); EncodingCombobox->setCurrentIndex(raw2edf_var->straightbinary); EncodingCombobox->setToolTip("bipolar offset binary or\n" "2's complement"); EndiannessLabel = new QLabel(raw2edfDialog); EndiannessLabel->setGeometry(20, 220, 140, 20); EndiannessLabel->setText("Endianness"); EndiannessCombobox = new QComboBox(raw2edfDialog); EndiannessCombobox->setGeometry(160, 220, 120, 20); EndiannessCombobox->addItem("little endian"); EndiannessCombobox->addItem("big endian"); EndiannessCombobox->setCurrentIndex(raw2edf_var->endianness); EndiannessCombobox->setToolTip("little endian: least significant byte comes first\n" "big endian: most significant byte comes first"); skipblocksizeLabel = new QLabel(raw2edfDialog); skipblocksizeLabel->setGeometry(320, 20, 140, 20); skipblocksizeLabel->setText("Data blocksize"); skipblocksizeSpinbox = new QSpinBox(raw2edfDialog); skipblocksizeSpinbox->setGeometry(460, 20, 120, 20); skipblocksizeSpinbox->setRange(0, 1000000); skipblocksizeSpinbox->setValue(raw2edf_var->skipblocksize); skipblocksizeSpinbox->setToolTip("Skip after every n databytes"); skipbytesLabel = new QLabel(raw2edfDialog); skipbytesLabel->setGeometry(320, 60, 140, 20); skipbytesLabel->setText("Skip bytes"); skipbytesSpinbox = new QSpinBox(raw2edfDialog); skipbytesSpinbox->setGeometry(460, 60, 120, 20); skipbytesSpinbox->setRange(1, 1000000); skipbytesSpinbox->setValue(raw2edf_var->skipbytes); skipbytesSpinbox->setToolTip("Number of bytes that must be skipped"); PhysicalMaximumLabel = new QLabel(raw2edfDialog); PhysicalMaximumLabel->setGeometry(320, 100, 140, 20); PhysicalMaximumLabel->setText("Physical maximum"); PhysicalMaximumSpinbox = new QSpinBox(raw2edfDialog); PhysicalMaximumSpinbox->setGeometry(460, 100, 120, 20); PhysicalMaximumSpinbox->setRange(1, 10000000); PhysicalMaximumSpinbox->setValue(raw2edf_var->phys_max); PhysicalMaximumSpinbox->setToolTip("The maximum physical value that can be measured\n" "e.g. the maximum value of an inputchannel."); PhysicalDimensionLabel = new QLabel(raw2edfDialog); PhysicalDimensionLabel->setGeometry(320, 140, 140, 20); PhysicalDimensionLabel->setText("Physical dimension"); PhysicalDimensionLineEdit = new QLineEdit(raw2edfDialog); PhysicalDimensionLineEdit->setGeometry(460, 140, 120, 20); PhysicalDimensionLineEdit->setMaxLength(8); PhysicalDimensionLineEdit->setText(raw2edf_var->phys_dim); PhysicalDimensionLineEdit->setToolTip("uV, bpm, mL, Ltr, etc."); PhysicalDimensionLineEdited(PhysicalDimensionLineEdit->text()); variableTypeLabel = new QLabel(raw2edfDialog); variableTypeLabel->setGeometry(320, 180, 140, 20); variableTypeLabel->setText("sampletype: i16"); PatientnameLabel = new QLabel(raw2edfDialog); PatientnameLabel->setGeometry(20, 260, 140, 20); PatientnameLabel->setText("Subject name"); PatientnameLineEdit = new QLineEdit(raw2edfDialog); PatientnameLineEdit->setGeometry(160, 260, 420, 20); PatientnameLineEdit->setMaxLength(80); RecordingLabel = new QLabel(raw2edfDialog); RecordingLabel->setGeometry(20, 300, 140, 20); RecordingLabel->setText("Recording"); RecordingLineEdit = new QLineEdit(raw2edfDialog); RecordingLineEdit->setGeometry(160, 300, 420, 20); RecordingLineEdit->setMaxLength(80); DatetimeLabel = new QLabel(raw2edfDialog); DatetimeLabel->setGeometry(20, 340, 140, 20); DatetimeLabel->setText("Startdate and time"); StartDatetimeedit = new QDateTimeEdit(raw2edfDialog); StartDatetimeedit->setGeometry(160, 340, 180, 20); StartDatetimeedit->setDisplayFormat("dd/MM/yyyy hh:mm:ss"); StartDatetimeedit->setDateTime(QDateTime::currentDateTime()); StartDatetimeedit->setToolTip("dd/MM/yyyy hh:mm:ss"); GoButton = new QPushButton(raw2edfDialog); GoButton->setGeometry(20, 440, 75, 25); GoButton->setText("Start"); GoButton->setToolTip("Start the conversion"); CloseButton = new QPushButton(raw2edfDialog); CloseButton->setGeometry(160, 440, 75, 25); CloseButton->setText("Close"); SaveButton = new QPushButton(raw2edfDialog); SaveButton->setGeometry(400, 440, 75, 25); SaveButton->setText("Save"); SaveButton->setToolTip("Save the entered parameters to a template for later use"); LoadButton = new QPushButton(raw2edfDialog); LoadButton->setGeometry(510, 440, 75, 25); LoadButton->setText("Load"); LoadButton->setToolTip("Load parameters from a template"); edfsignals = 1; QObject::connect(GoButton, SIGNAL(clicked()), this, SLOT(gobuttonpressed())); QObject::connect(CloseButton, SIGNAL(clicked()), raw2edfDialog, SLOT(close())); QObject::connect(SaveButton, SIGNAL(clicked()), this, SLOT(savebuttonpressed())); QObject::connect(LoadButton, SIGNAL(clicked()), this, SLOT(loadbuttonpressed())); QObject::connect(PhysicalDimensionLineEdit, SIGNAL(textEdited(QString)), this, SLOT(PhysicalDimensionLineEdited(QString))); QObject::connect(SampleSizeSpinbox, SIGNAL(valueChanged(int)), this, SLOT(sampleTypeChanged(int))); QObject::connect(EncodingCombobox, SIGNAL(currentIndexChanged(int)), this, SLOT(sampleTypeChanged(int))); sampleTypeChanged(0); raw2edfDialog->exec(); } void UI_RAW2EDFapp::gobuttonpressed() { int i, j, k, r, hdl, chns, sf, *buf, datarecords, tmp, straightbinary, samplesize, skipblocksize, skipbytes, skipblockcntr, bytecntr, big_endian; char str[256], path[MAX_PATH_LENGTH]; double phys_max; long long d_offset; FILE *inputfile; sf = SamplefreqSpinbox->value(); raw2edf_var->sf = sf; chns = SignalsSpinbox->value(); raw2edf_var->chns = chns; phys_max = PhysicalMaximumSpinbox->value(); raw2edf_var->phys_max = phys_max; straightbinary = EncodingCombobox->currentIndex(); raw2edf_var->straightbinary = straightbinary; big_endian = EndiannessCombobox->currentIndex(); raw2edf_var->endianness = big_endian; samplesize = SampleSizeSpinbox->value(); raw2edf_var->samplesize = samplesize; d_offset = OffsetSpinbox->value(); raw2edf_var->offset = d_offset; skipblocksize = skipblocksizeSpinbox->value(); raw2edf_var->skipblocksize = skipblocksize; skipbytes = skipbytesSpinbox->value(); raw2edf_var->skipbytes = skipbytes; strcpy(raw2edf_var->phys_dim, PhysicalDimensionLineEdit->text().toLatin1().data()); remove_leading_spaces(raw2edf_var->phys_dim); remove_trailing_spaces(raw2edf_var->phys_dim); if(!(strlen(PatientnameLineEdit->text().toLatin1().data()))) { QMessageBox messagewindow(QMessageBox::Critical, "Invalid input", "Please enter a subjectname."); messagewindow.exec(); return; } if(!(strlen(RecordingLineEdit->text().toLatin1().data()))) { QMessageBox messagewindow(QMessageBox::Critical, "Invalid input", "Please enter a recording description."); messagewindow.exec(); return; } strcpy(path, QFileDialog::getOpenFileName(0, "Open data file", QString::fromLocal8Bit(recent_opendir), "All files (*)").toLocal8Bit().data()); if(!strcmp(path, "")) { 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(); return; } remove_extension_from_filename(path); strcat(path, ".edf"); hdl = edfopen_file_writeonly(path, EDFLIB_FILETYPE_EDFPLUS, chns); if(hdl<0) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not open file for writing.\nedfopen_file_writeonly()"); messagewindow.exec(); fclose(inputfile); return; } for(i=0; iphys_dim)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "edf_set_physical_dimension()"); messagewindow.exec(); fclose(inputfile); return; } } for(i=0; idate().year(), StartDatetimeedit->date().month(), StartDatetimeedit->date().day(), StartDatetimeedit->time().hour(), StartDatetimeedit->time().minute(), StartDatetimeedit->time().second())) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "edf_set_startdatetime()"); messagewindow.exec(); fclose(inputfile); edfclose_file(hdl); return; } buf = (int *)malloc(sizeof(int) * sf * chns); if(buf == NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "malloc()"); messagewindow.exec(); fclose(inputfile); edfclose_file(hdl); return; } // printf("samplefrequency: %14i Hz\n" // "channels: %14i\n" // "physical maximum: %14.6f uV\n" // "straightbinary: %14i\n" // "samplesize: %14i byte(s)\n" // "offset: %14lli bytes\n" // "skip blocksize: %14i bytes\n" // "skip bytes: %14i bytes\n\n", // sf, // chns, // phys_max, // straightbinary, // samplesize, // d_offset, // skipblocksize, // skipbytes); fseeko(inputfile, d_offset, SEEK_SET); datarecords = 0; union{ int one[1]; signed short two[2]; char four[4]; } var; skipblockcntr = 0; bytecntr = 0; while(1) { for(j=0; j skipblocksize) { for(r=0; r skipblocksize) { for(r=0; r>= 8; } buf[j + (k * sf)] = var.two[0]; } } if(edf_blockwrite_digital_samples(hdl, buf)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Write error during conversion.\nedf_blockwrite_digital_samples()"); messagewindow.exec(); edfclose_file(hdl); fclose(inputfile); free(buf); return; } datarecords++; // if(datarecords == 1) break; } END_1: edfclose_file(hdl); fclose(inputfile); free(buf); sprintf(str, "A new EDF file has been created:\n\n%s", path); QMessageBox messagewindow(QMessageBox::Information, "Ready", str); messagewindow.setIconPixmap(QPixmap(":/images/ok.png")); messagewindow.exec(); } void UI_RAW2EDFapp::savebuttonpressed() { char path[MAX_PATH_LENGTH], str[128]; FILE *outputfile; raw2edf_var->sf = SamplefreqSpinbox->value(); raw2edf_var->chns = SignalsSpinbox->value(); raw2edf_var->phys_max = PhysicalMaximumSpinbox->value(); raw2edf_var->straightbinary = EncodingCombobox->currentIndex(); raw2edf_var->endianness = EndiannessCombobox->currentIndex(); raw2edf_var->samplesize = SampleSizeSpinbox->value(); raw2edf_var->offset = OffsetSpinbox->value(); raw2edf_var->skipblocksize = skipblocksizeSpinbox->value(); raw2edf_var->skipbytes = skipbytesSpinbox->value(); strcpy(raw2edf_var->phys_dim, PhysicalDimensionLineEdit->text().toLatin1().data()); remove_leading_spaces(raw2edf_var->phys_dim); remove_trailing_spaces(raw2edf_var->phys_dim); path[0] = 0; if(recent_savedir[0]!=0) { strcpy(path, recent_savedir); strcat(path, "/"); } strcat(path, "binary_to_edf.template"); strcpy(path, QFileDialog::getSaveFileName(0, "Save parameters", QString::fromLocal8Bit(path), "Template files (*.template *.TEMPLATE)").toLocal8Bit().data()); if(!strcmp(path, "")) { return; } get_directory_from_path(recent_savedir, path, MAX_PATH_LENGTH); outputfile = fopeno(path, "wb"); if(outputfile==NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not open file for writing."); messagewindow.exec(); return; } fprintf(outputfile, "\n<" PROGRAM_NAME "_raw2edf_template>\n"); fprintf(outputfile, " %i\n", raw2edf_var->sf); fprintf(outputfile, " %i\n", raw2edf_var->chns); fprintf(outputfile, " %i\n", raw2edf_var->phys_max); fprintf(outputfile, " %i\n", raw2edf_var->straightbinary); fprintf(outputfile, " %i\n", raw2edf_var->endianness); fprintf(outputfile, " %i\n", raw2edf_var->samplesize); fprintf(outputfile, " %i\n", raw2edf_var->offset); fprintf(outputfile, " %i\n", raw2edf_var->skipblocksize); fprintf(outputfile, " %i\n", raw2edf_var->skipbytes); xml_strcpy_encode_entity(str, raw2edf_var->phys_dim); fprintf(outputfile, " %s\n", str); fprintf(outputfile, "\n"); fclose(outputfile); } void UI_RAW2EDFapp::loadbuttonpressed() { char path[MAX_PATH_LENGTH], *result; struct xml_handle *xml_hdl; strcpy(path, QFileDialog::getOpenFileName(0, "Load parameters", QString::fromLocal8Bit(recent_opendir), "Template files (*.template *.TEMPLATE)").toLocal8Bit().data()); if(!strcmp(path, "")) { return; } get_directory_from_path(recent_opendir, path, MAX_PATH_LENGTH); xml_hdl = xml_get_handle(path); if(xml_hdl==NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not open file for reading."); messagewindow.exec(); return; } if(strcmp(xml_hdl->elementname, PROGRAM_NAME "_raw2edf_template")) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There seems to be an error in this template."); messagewindow.exec(); xml_close(xml_hdl); return; } if(!(xml_goto_nth_element_inside(xml_hdl, "sf", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } raw2edf_var->sf = atoi(result); if(raw2edf_var->sf < 1) raw2edf_var->sf = 1; if(raw2edf_var->sf > 1000000) raw2edf_var->sf = 1000000; free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "chns", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } raw2edf_var->chns = atoi(result); if(raw2edf_var->chns < 1) raw2edf_var->chns = 1; if(raw2edf_var->chns > 256) raw2edf_var->chns = 256; free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "phys_max", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } raw2edf_var->phys_max = atoi(result); if(raw2edf_var->phys_max < 1) raw2edf_var->phys_max = 1; if(raw2edf_var->phys_max > 10000000) raw2edf_var->phys_max = 10000000; free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "straightbinary", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } raw2edf_var->straightbinary = atoi(result); if(raw2edf_var->straightbinary < 0) raw2edf_var->straightbinary = 0; if(raw2edf_var->straightbinary > 1) raw2edf_var->straightbinary = 1; free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "endianness", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } raw2edf_var->endianness = atoi(result); if(raw2edf_var->endianness < 0) raw2edf_var->endianness = 0; if(raw2edf_var->endianness > 1) raw2edf_var->endianness = 1; free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "samplesize", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } raw2edf_var->samplesize = atoi(result); if(raw2edf_var->samplesize < 1) raw2edf_var->samplesize = 1; if(raw2edf_var->samplesize > 2) raw2edf_var->samplesize = 2; free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "offset", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } raw2edf_var->offset = atoi(result); if(raw2edf_var->offset < 0) raw2edf_var->offset = 0; if(raw2edf_var->offset > 1000000) raw2edf_var->offset = 1000000; free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "skipblocksize", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } raw2edf_var->skipblocksize = atoi(result); if(raw2edf_var->skipblocksize < 0) raw2edf_var->skipblocksize = 0; if(raw2edf_var->skipblocksize > 1000000) raw2edf_var->skipblocksize = 1000000; free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "skipbytes", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } raw2edf_var->skipbytes = atoi(result); if(raw2edf_var->skipbytes < 1) raw2edf_var->skipbytes = 1; if(raw2edf_var->skipbytes > 1000000) raw2edf_var->skipbytes = 1000000; free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "phys_dim", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } strncpy(raw2edf_var->phys_dim, result, 16); raw2edf_var->phys_dim[15] = 0; latin1_to_ascii(raw2edf_var->phys_dim, 16); remove_leading_spaces(raw2edf_var->phys_dim); remove_trailing_spaces(raw2edf_var->phys_dim); free(result); xml_go_up(xml_hdl); } xml_close(xml_hdl); SamplefreqSpinbox->setValue(raw2edf_var->sf); SignalsSpinbox->setValue(raw2edf_var->chns); PhysicalMaximumSpinbox->setValue(raw2edf_var->phys_max); EncodingCombobox->setCurrentIndex(raw2edf_var->straightbinary); EndiannessCombobox->setCurrentIndex(raw2edf_var->endianness); SampleSizeSpinbox->setValue(raw2edf_var->samplesize); OffsetSpinbox->setValue(raw2edf_var->offset); skipblocksizeSpinbox->setValue(raw2edf_var->skipblocksize); skipbytesSpinbox->setValue(raw2edf_var->skipbytes); } void UI_RAW2EDFapp::sampleTypeChanged(int) { if(SampleSizeSpinbox->value() == 1) { if(EncodingCombobox->currentIndex() == 0) { variableTypeLabel->setText("sampletype: I8"); } else { variableTypeLabel->setText("sampletype: U8"); } EndiannessCombobox->setEnabled(false); } else { if(EncodingCombobox->currentIndex() == 0) { variableTypeLabel->setText("sampletype: I16"); } else { variableTypeLabel->setText("sampletype: U16"); } EndiannessCombobox->setEnabled(true); } } void UI_RAW2EDFapp::PhysicalDimensionLineEdited(QString qstr) { qstr.prepend(" "); PhysicalMaximumSpinbox->setSuffix(qstr); } edfbrowser_153_source/PaxHeaders.2978/import_annotations.h0000644000175000001440000000013212251654530022247 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/import_annotations.h0000644000175000001440000001033612251654530022003 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef IMPORTANNOTATIONSFORM1_H #define IMPORTANNOTATIONSFORM1_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "mainwindow.h" #include "popup_messagewindow.h" #include "utc_date_time.h" #include "edf_annot_list.h" #include "utils.h" #include "annotations_dock.h" #include "xml.h" #include "edflib.h" #include "check_edf_file.h" #include "edf_annotations.h" class UI_Mainwindow; struct import_annotations_var_block { char separator[4]; int format; int onsettimeformat; int onsetcolumn; int descriptioncolumn; int manualdescription; int useduration; int durationcolumn; char description[21]; int datastartline; int dceventbittime; double triggerlevel; int ignoreconsecutive; }; class UI_ImportAnnotationswindow : public QObject { Q_OBJECT public: UI_ImportAnnotationswindow(QWidget *parent); UI_Mainwindow *mainwindow; private: QDialog *ImportAnnotsDialog; QTabWidget *tabholder; QWidget *tab[4]; QLabel *SeparatorLabel, *OnsetColumnLabel, *DatastartLabel, *OnsetTimeLabel, *DCEventSignalLabel, *DCEventBitTimeLabel, *DCEventTriggerLevelLabel; QLineEdit *SeparatorLineEdit, *DescriptionLineEdit; QSpinBox *OnsetColumnSpinBox, *DurationColumnSpinBox, *DescriptionColumnSpinBox, *DatastartSpinbox, *BitTimeSpinbox; QDoubleSpinBox *DCEventTriggerLevelSpinBox; QComboBox *RelativeTimeComboBox, *DCEventSignalComboBox; QVBoxLayout *asciiSettingsVBoxLayout, *DCEventVBoxLayout, *mainLayout; QHBoxLayout *asciiSettingsHBoxLayout1, *asciiSettingsHBoxLayout2, *asciiSettingsHBoxLayout3, *asciiSettingsHBoxLayout4, *asciiSettingsHBoxLayout5, *asciiSettingsHBoxLayout6, *asciiSettingsHBoxLayout7, *DCEventHBoxLayout1, *DCEventHBoxLayout2, *DCEventHBoxLayout3, *horLayout; QRadioButton *DescriptionColumnRadioButton, *UseManualDescriptionRadioButton; QCheckBox *IgnoreConsecutiveCheckBox, *DurationCheckBox; QPushButton *CloseButton, *ImportButton; int tab_index_array[4]; int import_from_xml(void); int import_from_ascii(void); int import_from_edfplus(void); int import_from_dcevent(void); private slots: void ImportButtonClicked(); void descriptionRadioButtonClicked(bool); void DCEventSignalChanged(int); void DurationCheckBoxChanged(int); void TabChanged(int); }; #endif edfbrowser_153_source/PaxHeaders.2978/check_edf_file.h0000644000175000001440000000013212251654530021212 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/check_edf_file.h0000644000175000001440000000317312251654530020747 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef CHECK_EDF_FILE1_H #define CHECK_EDF_FILE1_H #include #include #include #include "global.h" #include "utc_date_time.h" #include class EDFfileCheck { public: struct edfhdrblock * check_edf_file(FILE *, char *, int live_stream=0); private: struct edfhdrblock *edfhdr; int is_integer_number(char *); int is_number(char *); long long get_long_duration(char *); }; #endif // CHECK_EDF_FILE1_H edfbrowser_153_source/PaxHeaders.2978/edit_annotation_dock.cpp0000644000175000001440000000013212251654530023032 xustar000000000000000030 mtime=1386699096.477032522 30 atime=1386699096.477032522 30 ctime=1386699096.477032522 edfbrowser_153_source/edit_annotation_dock.cpp0000644000175000001440000002603012251654530022564 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "annotations_dock.h" UI_AnnotationEditwindow::UI_AnnotationEditwindow(int file_number, QWidget *w_parent) { mainwindow = (UI_Mainwindow *)w_parent; file_num = file_number; annotation = mainwindow->annotationlist[file_num]; dockedit = new QDockWidget("Annotation editor", w_parent); dockedit->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea); dockedit->setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetMovable); annot_edit_dialog = new QDialog; annot_edit_dialog->setMinimumSize(640, 45); dockedit->setWidget(annot_edit_dialog); descriptionLabel = new QLabel(annot_edit_dialog); descriptionLabel->setGeometry(10, 10, 78, 25); descriptionLabel->setText("Description"); annot_descript_lineEdit = new QLineEdit(annot_edit_dialog); annot_descript_lineEdit->setGeometry(90, 10, 150, 25); onsetLabel = new QLabel(annot_edit_dialog); onsetLabel->setGeometry(250, 10, 48, 25); onsetLabel->setText("Onset"); posNegTimebox = new QComboBox(annot_edit_dialog); posNegTimebox->setGeometry(300, 10, 35, 25); posNegTimebox->setEditable(FALSE); posNegTimebox->addItem("+"); posNegTimebox->addItem("-"); onset_daySpinbox = new QSpinBox(annot_edit_dialog); onset_daySpinbox->setGeometry(335, 10, 45, 25); onset_daySpinbox->setRange(0, 99); onset_daySpinbox->setSingleStep(1); onset_daySpinbox->setValue(0); onset_timeEdit = new QTimeEdit(annot_edit_dialog); onset_timeEdit->setGeometry(380, 10, 100, 25); onset_timeEdit->setDisplayFormat("hh:mm:ss.zzz"); onset_timeEdit->setMinimumTime(QTime(-1, 0, 0, 0)); durationLabel = new QLabel(annot_edit_dialog); durationLabel->setGeometry(490, 10, 58, 25); durationLabel->setText("Duration"); duration_spinbox = new QDoubleSpinBox(annot_edit_dialog); duration_spinbox->setGeometry(550, 10, 120, 25); duration_spinbox->setRange(-1.0, 10000.0); duration_spinbox->setSingleStep(1.0); duration_spinbox->setDecimals(3); duration_spinbox->setSuffix(" sec"); duration_spinbox->setValue(-1.0); modifybutton = new QPushButton(annot_edit_dialog); modifybutton->setGeometry(720, 10, 100, 25); modifybutton->setText("Modify"); modifybutton->setEnabled(FALSE); deletebutton = new QPushButton(annot_edit_dialog); deletebutton->setGeometry(840, 10, 100, 25); deletebutton->setText("Delete"); deletebutton->setEnabled(FALSE); createbutton = new QPushButton(annot_edit_dialog); createbutton->setGeometry(960, 10, 100, 25); createbutton->setText("Create"); QObject::connect(modifybutton, SIGNAL(clicked()), this, SLOT(modifyButtonClicked())); QObject::connect(deletebutton, SIGNAL(clicked()), this, SLOT(deleteButtonClicked())); QObject::connect(createbutton, SIGNAL(clicked()), this, SLOT(createButtonClicked())); QObject::connect(dockedit, SIGNAL(visibilityChanged(bool)), this, SLOT(open_close_dock(bool))); } void UI_AnnotationEditwindow::open_close_dock(bool visible) { if(visible==TRUE) { mainwindow->annot_editor_active = 1; mainwindow->show_annot_markers = 1; if(mainwindow->annotationlist_backup==NULL) { mainwindow->annotationlist_backup = edfplus_annotation_copy_list(&mainwindow->annotationlist[0]); } } else { modifybutton->setEnabled(FALSE); deletebutton->setEnabled(FALSE); mainwindow->annot_editor_active = 0; } } void UI_AnnotationEditwindow::modifyButtonClicked() { annotation = edfplus_annotation_item(&mainwindow->annotationlist[file_num], annot_num); annotation->onset = onset_daySpinbox->value() * 86400 * TIME_DIMENSION; annotation->onset += onset_timeEdit->time().hour() * 3600 * TIME_DIMENSION; annotation->onset += onset_timeEdit->time().minute() * 60 * TIME_DIMENSION; annotation->onset += onset_timeEdit->time().second() * TIME_DIMENSION; annotation->onset += onset_timeEdit->time().msec() * (TIME_DIMENSION / 1000); if(posNegTimebox->currentIndex() == 1) { annotation->onset = -(annotation->onset); } annotation->onset += mainwindow->edfheaderlist[file_num]->starttime_offset; if(duration_spinbox->value()>0.0) { snprintf(annotation->duration, 16, "%f", duration_spinbox->value()); } else { annotation->duration[0] = 0; } strncpy(annotation->annotation, annot_descript_lineEdit->text().toUtf8().data(), MAX_ANNOTATION_LEN); annotation->annotation[MAX_ANNOTATION_LEN] = 0; annotation->modified = 1; annotation->selected = 1; mainwindow->annotations_edited = 1; mainwindow->annotations_dock[file_num]->updateList(); mainwindow->maincurve->update(); } void UI_AnnotationEditwindow::deleteButtonClicked() { edfplus_annotation_delete(&mainwindow->annotationlist[file_num], annot_num); annotation = edfplus_annotation_item(&mainwindow->annotationlist[file_num], annot_num); if(annotation!=NULL) { annotation->selected = 1; annotation->jump = 1; } modifybutton->setEnabled(FALSE); deletebutton->setEnabled(FALSE); mainwindow->annotations_edited = 1; mainwindow->save_act->setEnabled(TRUE); mainwindow->annotations_dock[file_num]->updateList(); mainwindow->maincurve->update(); } void UI_AnnotationEditwindow::createButtonClicked() { annotation = (struct annotationblock *)calloc(1, sizeof(struct annotationblock)); annotation->onset = onset_daySpinbox->value() * 86400 * TIME_DIMENSION; annotation->onset += onset_timeEdit->time().hour() * 3600 * TIME_DIMENSION; annotation->onset += onset_timeEdit->time().minute() * 60 * TIME_DIMENSION; annotation->onset += onset_timeEdit->time().second() * TIME_DIMENSION; annotation->onset += onset_timeEdit->time().msec() * (TIME_DIMENSION / 1000); if(posNegTimebox->currentIndex() == 1) { annotation->onset = -(annotation->onset); } annotation->onset += mainwindow->edfheaderlist[file_num]->starttime_offset; annotation->file_num = file_num; if(duration_spinbox->value()>0.0) { snprintf(annotation->duration, 16, "%f", duration_spinbox->value()); } else { annotation->duration[0] = 0; } strncpy(annotation->annotation, annot_descript_lineEdit->text().toUtf8().data(), MAX_ANNOTATION_LEN); annotation->annotation[MAX_ANNOTATION_LEN] = 0; annotation->modified = 1; edfplus_annotation_add_item(&mainwindow->annotationlist[file_num], annotation); mainwindow->annotations_edited = 1; mainwindow->annotations_dock[file_num]->updateList(); mainwindow->maincurve->update(); } void UI_AnnotationEditwindow::annotEditSetOnset(long long onset) { QTime ta; if(onset < 0LL) { onset_daySpinbox->setValue((-(onset)) / TIME_DIMENSION / 86400); ta.setHMS(((-(onset)) / TIME_DIMENSION / 3600) % 24, (((-(onset)) / TIME_DIMENSION) % 3600) / 60, ((-(onset)) / TIME_DIMENSION) % 60, ((-(onset)) % TIME_DIMENSION) / 10000); posNegTimebox->setCurrentIndex(1); } else { onset_daySpinbox->setValue(onset / TIME_DIMENSION / 86400); ta.setHMS((onset / TIME_DIMENSION / 3600) % 24, ((onset / TIME_DIMENSION) % 3600) / 60, (onset / TIME_DIMENSION) % 60, (onset % TIME_DIMENSION) / 10000); posNegTimebox->setCurrentIndex(0); } onset_timeEdit->setTime(ta); } void UI_AnnotationEditwindow::annotEditSetDuration(long long duration) { double tmp; tmp = duration; tmp /= TIME_DIMENSION; duration_spinbox->setValue(tmp); } void UI_AnnotationEditwindow::set_selected_annotation(int file_nr, int annot_nr) { long long l_tmp; QTime ta; file_num = file_nr; annot_num = annot_nr; annotation = edfplus_annotation_item(&mainwindow->annotationlist[file_num], annot_num); annot_descript_lineEdit->setText(QString::fromUtf8(annotation->annotation)); l_tmp = annotation->onset - mainwindow->edfheaderlist[annotation->file_num]->starttime_offset; if(l_tmp < 0LL) { onset_daySpinbox->setValue((-(l_tmp)) / TIME_DIMENSION / 86400); ta.setHMS(((-(l_tmp)) / TIME_DIMENSION / 3600) % 24, (((-(l_tmp)) / TIME_DIMENSION) % 3600) / 60, ((-(l_tmp)) / TIME_DIMENSION) % 60, ((-(l_tmp)) % TIME_DIMENSION) / 10000); posNegTimebox->setCurrentIndex(1); } else { onset_daySpinbox->setValue(l_tmp / TIME_DIMENSION / 86400); ta.setHMS((l_tmp / TIME_DIMENSION / 3600) % 24, ((l_tmp / TIME_DIMENSION) % 3600) / 60, (l_tmp / TIME_DIMENSION) % 60, (l_tmp % TIME_DIMENSION) / 10000); posNegTimebox->setCurrentIndex(0); } onset_timeEdit->setTime(ta); if(strlen(annotation->duration)) { duration_spinbox->setValue(atof(annotation->duration)); } else { duration_spinbox->setValue(-1); } modifybutton->setEnabled(TRUE); deletebutton->setEnabled(TRUE); } void UI_AnnotationEditwindow::set_selected_annotation(struct annotationblock *annot) { long long l_tmp; QTime ta; annotation = annot; file_num = annot->file_num; annot_descript_lineEdit->setText(QString::fromUtf8(annotation->annotation)); l_tmp = annotation->onset - mainwindow->edfheaderlist[annotation->file_num]->starttime_offset; if(l_tmp < 0LL) { onset_daySpinbox->setValue((-(l_tmp)) / TIME_DIMENSION / 86400); ta.setHMS(((-(l_tmp)) / TIME_DIMENSION / 3600) % 24, (((-(l_tmp)) / TIME_DIMENSION) % 3600) / 60, ((-(l_tmp)) / TIME_DIMENSION) % 60, ((-(l_tmp)) % TIME_DIMENSION) / 10000); posNegTimebox->setCurrentIndex(1); } else { onset_daySpinbox->setValue(l_tmp / TIME_DIMENSION / 86400); ta.setHMS((l_tmp / TIME_DIMENSION / 3600) % 24, ((l_tmp / TIME_DIMENSION) % 3600) / 60, (l_tmp / TIME_DIMENSION) % 60, (l_tmp % TIME_DIMENSION) / 10000); posNegTimebox->setCurrentIndex(0); } onset_timeEdit->setTime(ta); if(strlen(annotation->duration)) { duration_spinbox->setValue(atof(annotation->duration)); } else { duration_spinbox->setValue(-1); } modifybutton->setEnabled(FALSE); deletebutton->setEnabled(FALSE); } edfbrowser_153_source/PaxHeaders.2978/scp_ecg2edf.h0000644000175000001440000000013212251654530020464 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/scp_ecg2edf.h0000644000175000001440000000712412251654530020221 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef UI_SCPECG2EDFFORM_H #define UI_SCPECG2EDFFORM_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "utils.h" #include "edflib.h" #include "utc_date_time.h" class UI_SCPECG2EDFwindow : public QObject { Q_OBJECT public: UI_SCPECG2EDFwindow(char *recent_dir=NULL, char *save_dir=NULL); private: QPushButton *pushButton1, *pushButton2; QTextEdit *textEdit1; QDialog *myobjectDialog; char *recent_opendir, *recent_savedir; unsigned short crc_ccitt_table[256]; struct section_prop_struct{ int present; long long file_offset; unsigned short crc; int section_id; int section_length; int section_version; int section_protocol_version; char reserved[6]; } sp[12]; struct lead_prop_struct{ int start; int end; int samples; int bytes; unsigned char label; } lp[256]; struct huffmantable_struct{ int h_tables_cnt; int code_structs_cnt; int prefix_bits; int total_bits; int table_mode_switch; int base_value; int base_code; } ht; struct patient_data_struct{ char pat_id[21]; int startdate_year; int startdate_month; int startdate_day; int starttime_hour; int starttime_minute; int starttime_second; char last_name[21]; char first_name[21]; int birthdate_year; int birthdate_month; int birthdate_day; int sex; char device_model[6]; char device_serial[49]; char device_ident[49]; char manufacturer[49]; unsigned char lang_code; } pat_dat; int read_data_section_zero(FILE *, char *, long long); int read_section_header(int, FILE *, long long, char *); int check_crc(FILE *, long long, long long, unsigned short, char *); void crc_ccitt_init(void); unsigned short crc_ccitt(const unsigned char *, int, unsigned short); inline unsigned char reverse_bitorder(unsigned char); void lead_label_lookup(unsigned char, char *); int get_patient_data(FILE *); private slots: void SelectFileButton(); }; #endif edfbrowser_153_source/PaxHeaders.2978/save_montage_dialog.cpp0000644000175000001440000000013212251654530022642 xustar000000000000000030 mtime=1386699096.479032511 30 atime=1386699096.479032511 30 ctime=1386699096.479032511 edfbrowser_153_source/save_montage_dialog.cpp0000644000175000001440000002140012251654530022370 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "save_montage_dialog.h" #if defined(__APPLE__) || defined(__MACH__) || defined(__APPLE_CC__) #define fopeno fopen #else #define fseeko fseeko64 #define ftello ftello64 #define fopeno fopen64 #endif UI_SaveMontagewindow::UI_SaveMontagewindow(QWidget *w_parent) { int i; mainwindow = (UI_Mainwindow *)w_parent; if(mainwindow->files_open==1) { SaveMontageDialog = NULL; SaveButtonClicked(); return; } SaveMontageDialog = new QDialog; SaveMontageDialog->setMinimumSize(QSize(800, 180)); SaveMontageDialog->setMaximumSize(QSize(800, 180)); SaveMontageDialog->setWindowTitle("Save montage"); SaveMontageDialog->setModal(TRUE); SaveMontageDialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); label1 = new QLabel(SaveMontageDialog); label1->setGeometry(QRect(10, 10, 780, 25)); label1->setText("Choose from which file you want to save the montage:"); filelist = new QListWidget(SaveMontageDialog); filelist->setGeometry(QRect(10, 35, 780, 75)); filelist->setSelectionBehavior(QAbstractItemView::SelectRows); filelist->setSelectionMode(QAbstractItemView::SingleSelection); for(i=0; ifiles_open; i++) { new QListWidgetItem(QString::fromLocal8Bit(mainwindow->edfheaderlist[i]->filename), filelist); } SaveButton = new QPushButton(SaveMontageDialog); SaveButton->setGeometry(QRect(10, 140, 100, 25)); SaveButton->setText("Save"); CloseButton = new QPushButton(SaveMontageDialog); CloseButton->setGeometry(QRect(690, 140, 100, 25)); CloseButton->setText("Close"); QObject::connect(CloseButton, SIGNAL(clicked()), SaveMontageDialog, SLOT(close())); QObject::connect(SaveButton, SIGNAL(clicked()), this, SLOT(SaveButtonClicked())); filelist->setCurrentRow(mainwindow->files_open - 1); SaveMontageDialog->exec(); } void UI_SaveMontagewindow::SaveButtonClicked() { int i, j, n; char mtg_path[MAX_PATH_LENGTH]; FILE *mtgfile; if(mainwindow->files_open==1) n = 0; else n = filelist->currentRow(); strcpy(mtg_path, mainwindow->recent_montagedir); strcat(mtg_path, "/my_montage.mtg"); strcpy(mtg_path, QFileDialog::getSaveFileName(0, "Save montage", QString::fromLocal8Bit(mtg_path), "Montage files (*.mtg *.MTG)").toLocal8Bit().data()); if(!strcmp(mtg_path, "")) { return; } if(strlen(mtg_path) > 4) { if(strcmp(mtg_path + strlen(mtg_path) - 4, ".mtg")) { strcat(mtg_path, ".mtg"); } } get_directory_from_path(mainwindow->recent_montagedir, mtg_path, MAX_PATH_LENGTH); mtgfile = fopeno(mtg_path, "wb"); if(mtgfile==NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not open file for writing."); messagewindow.exec(); return; } fprintf(mtgfile, "\n<" PROGRAM_NAME "_montage>\n"); for(i=0; isignalcomps; i++) { if(!strcmp(mainwindow->signalcomp[i]->edfhdr->filename, mainwindow->edfheaderlist[n]->filename)) { fprintf(mtgfile, " \n"); fprintf(mtgfile, " "); xml_fwrite_encode_entity(mtgfile, mainwindow->signalcomp[i]->alias); fprintf(mtgfile, "\n"); fprintf(mtgfile, " %i\n", mainwindow->signalcomp[i]->num_of_signals); fprintf(mtgfile, " %f\n", mainwindow->signalcomp[i]->voltpercm); fprintf(mtgfile, " %f\n", mainwindow->signalcomp[i]->screen_offset); fprintf(mtgfile, " %i\n", mainwindow->signalcomp[i]->polarity); fprintf(mtgfile, " %i\n", mainwindow->signalcomp[i]->color); fprintf(mtgfile, " %i\n", mainwindow->signalcomp[i]->filter_cnt); fprintf(mtgfile, " %i\n", mainwindow->signalcomp[i]->fidfilter_cnt); fprintf(mtgfile, " %i\n", mainwindow->signalcomp[i]->ravg_filter_cnt); for(j=0; jsignalcomp[i]->num_of_signals; j++) { fprintf(mtgfile, " \n"); fprintf(mtgfile, " \n"); fprintf(mtgfile, " %i\n", mainwindow->signalcomp[i]->factor[j]); fprintf(mtgfile, " \n"); } for(j=0; jsignalcomp[i]->filter_cnt; j++) { fprintf(mtgfile, " \n"); fprintf(mtgfile, " %i\n", mainwindow->signalcomp[i]->filter[j]->is_LPF); fprintf(mtgfile, " %.16f\n", mainwindow->signalcomp[i]->filter[j]->cutoff_frequency); fprintf(mtgfile, " \n"); } for(j=0; jsignalcomp[i]->ravg_filter_cnt; j++) { fprintf(mtgfile, " \n"); fprintf(mtgfile, " %i\n", mainwindow->signalcomp[i]->ravg_filter[j]->type); fprintf(mtgfile, " %i\n", mainwindow->signalcomp[i]->ravg_filter[j]->size); fprintf(mtgfile, " \n"); } for(j=0; jsignalcomp[i]->fidfilter_cnt; j++) { fprintf(mtgfile, " \n"); fprintf(mtgfile, " %i\n", mainwindow->signalcomp[i]->fidfilter_type[j]); fprintf(mtgfile, " %.16f\n", mainwindow->signalcomp[i]->fidfilter_freq[j]); fprintf(mtgfile, " %.16f\n", mainwindow->signalcomp[i]->fidfilter_freq2[j]); fprintf(mtgfile, " %.16f\n", mainwindow->signalcomp[i]->fidfilter_ripple[j]); fprintf(mtgfile, " %i\n", mainwindow->signalcomp[i]->fidfilter_order[j]); fprintf(mtgfile, " %i\n", mainwindow->signalcomp[i]->fidfilter_model[j]); fprintf(mtgfile, " \n"); } if(mainwindow->signalcomp[i]->ecg_filter != NULL) { fprintf(mtgfile, " \n"); fprintf(mtgfile, " 1\n"); fprintf(mtgfile, " \n"); } if(mainwindow->signalcomp[i]->zratio_filter != NULL) { fprintf(mtgfile, " \n"); fprintf(mtgfile, " 1\n"); fprintf(mtgfile, " %f\n", mainwindow->signalcomp[i]->zratio_crossoverfreq); fprintf(mtgfile, " \n"); } if(mainwindow->signalcomp[i]->hasruler) { fprintf(mtgfile, " \n"); fprintf(mtgfile, " 1\n"); fprintf(mtgfile, " %i\n", mainwindow->maincurve->ruler_x_position); fprintf(mtgfile, " %i\n", mainwindow->maincurve->ruler_y_position); fprintf(mtgfile, " %i\n", mainwindow->maincurve->floating_ruler_value); fprintf(mtgfile, " \n"); } fprintf(mtgfile, " \n"); } } #ifdef Q_WS_WIN fprintf(mtgfile, " %I64d\n", mainwindow->pagetime); #else fprintf(mtgfile, " %lli\n", mainwindow->pagetime); #endif fprintf(mtgfile, "\n"); fclose(mtgfile); if(mainwindow->files_open == 1) { strcpy(&mainwindow->recent_file_mtg_path[0][0], mtg_path); } if(SaveMontageDialog!=NULL) SaveMontageDialog->close(); } edfbrowser_153_source/PaxHeaders.2978/version.txt0000644000175000001440000000012712251654530020401 xustar000000000000000029 mtime=1386699096.50403238 29 atime=1386699096.50403238 29 ctime=1386699096.50403238 edfbrowser_153_source/version.txt0000644000175000001440000005517412251654530020142 0ustar00novarausers00000000000000 version 1.53 December 10, 2013 ------------ - The activity of the floating ruler will now be stored in the montages as well. - Added a filter to the annotationslist. - Modified the BI9800 to EDF converter to make it work with 48-hour recordings. - Made the viewtime (fileposition) indicator configurable. Added the date to the viewtime indicator in the left down corner of the screen. This can be configured in the settings menu. - Made the window title bar configurable. This can be configured in the settings menu. - fixed a bug in the EDF+D to EDF+C converter. - Added the possibility to save and load different color schemas. - Added support for the Unisens fileformat. You will find the converter in the Tools menu. - Added the possibility to save and load colorschemas. version 1.52 September 7, 2013 ------------ - Added an SCP-ECG file to EDF+ converter. Bimodal compression or customized Hufmanntables are not supported. Lossless compression using default Hufmanntable and/or 1th/2th differences is supported. Character-encoding other than ASCII/Latin-1 is not supported. - Added two shortcuts (Plus and Minus keys) to increase or decrease the amplitude of the signals (sensitivity). - Added the possibility to choose between little endian or big endian encoding in the binary/raw to EDF converter tool. - Increased the number of pre-defined montage shortcuts from 8 to 12 (keys F1 to F12). - Added the possibility to use aliases for the signallabels on the screen. - Qt has been updated to 4.8.5. version 1.51 May 11, 2013 ------------ - Added a Manscan MICROAMPS binary file to EDF+ converter. - Solved another bug in the sorting algorithm used for the annotationlist. version 1.50 April 20, 2013 ------------ - Fixed a bug in the ECG heartrate detection algorithm when a high samplerate was used. - Improved the sorting algorithm used for the annotationlist, it was very slow when the annotationlist contains more than 10000 annotations. - Added the possibility to adjust the samplerate divider for all signals at once in the reducer/decimator tool. - EDFbrowser now checks online for a newer version during startup. This can be switched off in the settings menu. version 1.49 February 5, 2013 ------------ - Added a binary/raw to EDF converter tool. - Solved a bug in the "Import annotations" tool. When importing from ascii, wrong onset-times were created when there were more than 7 digits after the decimal point. - Added a scrollbar to the options- / settingsdialog in order to make it fit on screens with low vertical height (modern laptops with 16:9 screen). - Removed GTK-style support because it's broken. - Updated Qt to 4.8.4 version 1.48 June 8, 2012 ------------ - Added sub-second precision for annotations when using the Nihon Kohden converter. (Before, the onsettimes of the annotations were rounded to seconds.) - Added Z-EEG measurement. - Improved the header editor/fixer. Now it accepts files with a maximum of 2048 signals. (Before it was limited to files with a maximum of 256 signals.) Now, it can also fix the digital minimum/maximum fields in the header (e.g. when a broken number was written instead of an integer number). - Updated Qt to 4.8.2 version 1.47 May 7, 2012 ------------ - Solved a bug that caused a crash when saving an EDF- or BDF-file after importing annotations. - Changed the "Export ECG RR-interval" tool in such a way that you can easily export the whole recording. Also, now it's possible to import them as annotations directly. - The tool "Import annotations/events" can now also import the duration of an annotation/event (from ASCII- or XML-files). - Added the possibility to hide or unhide annotations from the screen. (Right-click on an annotation in the annotationswindow.) version 1.46 April 13, 2012 ------------ - Solved a bug that caused a crash when the "Abort" button was clicked when opening a BDF-file. - Solved some small bugs and made some enhancements. - Updated Qt to 4.8.1. version 1.45 March 31, 2012 ------------ - Added the possibility to disable scanning for annotations or triggers when opening a file, depending of the filesize. This can be useful when working with big files that take a lot of time to read-in annotations, events or triggers. (Due to the nature of the EDF-format, the annotations-channel(s) needs to be read from the beginning till the end of the file.) In the "Settings -> other" dialog you can adjust the filesize which above EDFbrowser will not scan the file for annotations. (between 100 MB and 10 GB) - extended the capabilities of the header-editor. Now it can also fix files that have a wrong number of datarecords written in the header or when the file does not end at the boundary of a datarecord. See the manual for the details. - Improved the ECG heartrate detection algorithm. - Fixed some bugs related to signals with inversed polarity (i.e. when physical maximum is lower than physical minimum). version 1.44 March 4, 2012 ------------ - Fixed a bug that caused the "print to PDF / Postscript / Image" to fail when non-ascii characters where present in the new filename. - Fixed a bug that caused "printing to image" drawing the signals too thick and wrong rulers. - Fixed a bug in the ECG heartrate detection algorithm that could cause wrong measurements with high heartrates (more than 120 bpm). - Added Mousewheel zoom-in/out by pressing the Ctrl-key. version 1.43 Februari 17, 2012 ------------ - Fixed multiple bugs related to annotationmarkers and EDFplus feature to use subsecondprecision in the starttime of the file. (Only affects files that uses the subsecond starttime offset EDF+ feature.) version 1.42 Februari 1, 2012 ------------ - Fixed a problem with EDFbrowser not capable to handle filenames and/or directories that contain non-ascii characters. From now on, filenames/paths will be handled and saved using the local 8-bit encoding. - Added multi-threading capabilities to the drawing engine. EDFbrowser will now use all available cpu-cores in your system to speedup the drawing of the signals. version 1.41 December 4, 2011 ------------ - Fixed a bug (introduced with ver. 1.40) that caused a long time to open an EDF+ or BDF+ file when it contains many annotations. - Improved printing quality. On some printers or pdf-readers, the signals and rulers were hardly visible because the linewidth was too small. - Added the possibility to set the colors of the averaging window to black/white. - Added the possibility to check for and remove duplicate annotations (Tools menu). version 1.40 December 1, 2011 ------------ - Added the possibility to reduce the samplerate of one or more signals in the tool "Reduce signals, duration or samplerate" (Tools menu). - Added the possibility to change/edit the starttime/date of a file with the EDF/BDF header editor (Tools menu). - The Statistics dialog shows also the number of zero-crossings and the frequency of a signal. - The Nihon Kohden to EDF+ converter now processes also the Trigger/Marker channel. For example, photo- or dc-triggers will be processed by the converter and can be displayed by EDFbrowser. - Fixed a bug in the signalcurve (graph) of the averaging window, when "invert" was selected, the vertical ruler could disappear. - Fixed a bug in the floating ruler. - Raised the maximum amount of signals per file limit from 256 to 512. version 1.39 September 20, 2011 ------------ - Fixed another bug related to annotationmarkers and EDFplus feature to use subsecondprecision in the starttime of the file. - Updated Qt to 4.7.4 version 1.38 August 24, 2011 ------------ - Fixed lots of regression bugs introduced with version 1.37. - Fixed a bug related to annotationmarkers and EDFplus feature to use subsecondprecision in the starttime of the file. - Fixed a bug in the ascii to edf converter that caused to produce an invalid edf file when all samples in have value "0.0". version 1.37 August 17, 2011 ------------ - Removed the limitation that no more annotations can be saved than the amount of datarecords. EDFbrowser could only write one annotation per datarecord. From now on, if there are more annotations than datarecords, the size (smpls/record) of the annotationchannel will increase automatically in order to fit multiple annotations as needed. version 1.36 June 16, 2011 ------------ - Solved a bug when importing events/annotations from an ascii-file. version 1.35 June 16, 2011 ------------ - Changed the selectionbehaviour of the signallist in Signals -> Organize. Now you can select multiple signals when organizing the signals on the screen. - Solved a bug that caused showing the wrong signal when there are duplicate signalnames in a file. - Solved a bug that caused a cryptic error message "avg_cnt is ..." when averaging a signal using a trigger/annotation which was not inside the selected timewindow. - Now it is possible to start/open multiple averagingwindows applied on the same signal. - Added the possibility to invert te waveform of the averagingwindow. - Solved a bug that caused an errormessage when trying to open a large file (>2.1GB) on a Mac. - Removed some bugs in the heartrate detection code. - Now you can choose between different kinds of data (R onset or RR-interval or both) when exporting the heartrate data. version 1.34 May 9, 2011 ------------ - Added ECG heartrate detection (it calculates beats per minute from the ECG-waveform). - Added the possibility to import annotations, also from discontinues EDF+D or BDF+D files. - Added mousewheel scrolling. - Added the possibility to save the data from averaging as EDF/BDF. - Added the possibility to (re-)organize (re-order and/or invert) the signals on the screen in an easy way via Menu -> Signals -> Organize. - Modified the annotation editor, from now on annotations with an onsettime more than 24 hours can be edited as well. - Solved a bug that prevented a messagebox to appear when trying to open a BDF+D file. - Changed the way the onsettime of the annotations are presented. version 1.33 March 22, 2011 ------------ - Added the possibility to import/extract triggers/events from/recorded on a dc-coupled channel. - Added the possibility to perform "averaging" (evoked potentials or other triggers) using (imported) annotations, events or other kind of triggers. - Added a WAV to EDF converter. - Modified the Nihon Kohden to EDF converter so that it will use the electrodenames defined by the user in the aquisition software. - Fixed a bug that caused writing a wrong value in the datarecorddurationfield of the header when saving annotations and when the number in the datarecorddurationfield of the sourcefile has more than six digits after the dot. - Fixed a bug related to a rarely used EDFplus feature to use subsecondprecision in the starttime of the file. Some tools ignored this feature, this has been fixed. - Updated Qt to 4.7.2 version 1.32 December 16, 2010 ------------ - Fixed a bug that prevented from updating the screen when in streaming mode and after all signals were removed. - Fixed a bug in EDFlib. version 1.31 December 8, 2010 ------------ - Added a streaming mode. The stream must be a "growing" file. This mode can be used when you have an aquisitionprogram running that writes EDF or BDF. While the aquisitionprogram writes the data to the file, you can use EDFbrowser to watch (follow) the actual data. EDFbrowser will regularly check the actual filesize and show the last part of the file i.e. the most actual/recent data. - Added a "moving average" filtermodel (high- and lowpass). - The "View montage" dialogs got a facelift. version 1.30 November 24, 2010 ------------ - Added the possibility to import events/annotations from a text/csv or XML file. - Enhanced the "Export annotations/events" tool. Now you can choose the separator character (comma or tab) and you can choose different ISO time (and date) timestamps encodings. XML export is possible as well. - Solved a bug in de the "adjust filter" dialogue. When using a notchfilter, the "order" widget was shown instead of the "Q-factor" widget. - Updated Qt to version 4.7.1. version 1.29 November 9, 2010 ------------ - Added the possibility to adjust the filter settings while watching the result (realtime). - Fixed a bug that caused the program to remember the wrong montage. - Added a possibility in the ASCII to EDF converter to detect the physical maximum values of the signals automatically. - The ASCII to EDF converter can also convert to BDF (24-bit). version 1.28 October 27, 2010 ------------ - Added support for reading the "Status" signal in Biosemi data files. This can be switched on/off in the settings menu. - Added a Biosemi to BDF+ converter. It converts the Biosemi trigger inputs to annotations which can be read and processed by EDFbrowser. - Added an EDF-converter for the Bmeye Nexfin / FrameInspector csv-output (beat-to-beat data, bloodpressure waveform, analog inputs). - Added zoom-in/zoom-out function using Ctrl++ and Ctrl--. - Added keyboard shortcuts and accelerators to the menu's. - From now on, the timescale will be saved in montages as well. - When opening a file, the last used montage (with that file) will be applied automatically. This behaviour can be switched off in the settingsmenu. version 1.27 September 27, 2010 ------------ - Made all the file-open/save dialogs native. This improves the speed in file-listing on some windows-pc's. version 1.26 September 7, 2010 ------------ - Added an header-editor. - Added a file reducer/cropper. - Added the possibility to clip the signals to their pane. - Solved a bug that rendered the settingsmenu invisible on the Mac. version 1.25 August 2, 2010 ------------ - Solved a bug that caused writing invalid files and/or caused to reject opening a file because of an incompatibility while in reality the file was valid. This was caused by a localizationproblem which occured only on systems where countrysettings are used that uses a comma as a decimal separator. - Changed the name of the "Display" menu to "Timescale". - Added the entry "3 cm/sec" to the the Timescale menu. - From now on EDFbrowser will use the DPI-settings from the underlying windowmanager in order to calibrate the screen. If this doesn't work well in your situation, you can still calibrate the screen manually in the settingsmenu. - Solved a bug that caused malformed waveforms when opening large files (>4 GB) and when navigating to the end of the file. This was caused by an integer overflow. - Solved a bug in the ASCII to EDF converter (couldn't open templates). - Changed the sourcecode to improve Mac compatibility. version 1.24 June 28, 2010 ------------ - Solved a bug in the Nihon Kohden to EDF+ converter that caused a message "Can not open file *.log for reading,". version 1.23 June 23, 2010 ------------ - Changed the DFT-algorithm of the powerspectrum to an FFT-algorithm in order to avoid long computation times. - Added the possibility to adjust the blocksize for the powerspectrum (FFT). - Added an extra option to the Annotations export tool. Now you can choose to save the annotations in a comma separated textfile or in the EDFplus format. - Changed the position of the widgets in the annotation-editor window. The "Create" button will not be cut-off anymore when a monitor with a resolution of 1024 x 768 is used. - Qt has been updated to version 4.6.3 (windows version has still 4.6.2). version 1.22 june 4, 2010 ------------ - Added a docked powerspectrum which updates automatically when you navigate throug a file (PgUp,PgDn, etc,). - Added the possibility to use different backgroundcolors for different frequencyregions in the docked powerspectrum (colorbars). - Added an export function for the powerspectrum. This will export the data of the powerspectrum to a textfile. - Added a cursor to the powerspectrum. - Improved the way filters run-in. - Added an export function for annotations. This will export the annotations to a comma separated textfile. - Added a possibility to bind keys F1 ... F8 to predefined montages. This way you can quickly switch between different montages by pressing F1, F2, etc. - Removed a bug in the EDF+D to EDF+C converter that could cause a crash. - Removed a bug in the BDF+ to ASCII converter. version 1.21 may 11, 2010 ------------ - The Powerspectrum window will not block the mainwindow anymore. Now you can open multiple Powerspectrum windows (for example, to compare different blocks of data and/or different signals). - Made a printing option for the Powerspectrum. you can print the Powerspectrum to a printer, Postscript, PDF or an image by rightclicking on the curve of the Powerspectrum. - The ASCII to EDF converter now has a multiplierfactor. Cleaned up the code of the converter as well. - Fixed a bug that caused writing to a freed memory area which could cause a crash when closing the program (mainly noticeable on windows). - Fixed a memoryleak. version 1.20 may 4, 2010 ------------ - Added a power spectrum analyzer (Discrete Fourier Transform). - Removed a bug that caused wrong vertical ruler values during printing. - Removed a bug that caused a wrong screenoffset when changing the offset in the signalproperties dialog. version 1.19 april 20, 2010 ------------ - Added extra filter options: lowpass, highpass, notch, bandpass, bandstop, Butterworth, Chebyshev, Bessel, 1,2,3,...8 th order, adjustable bandpassripple or Q-factor. - Removed a bug in the BDF to EDF converter, clicking on "Select all signals" or "Deselect all signals" without a selected file, caused a crash. - Fixed a bug in the "Print to EDF" and "Print to BDF" function. Filter description in header was wrong (i.e. "LPF:" instead of "LP:"). - Fixed a bug in the Filter Dialog. When adding a new filter when signals have different samplerates, initialisation of the new filter could happen with wrong samplerate, causing a wrong frequency of the filter. - Updated Qt to version 4.6.2 version 1.18 januari 12, 2010 ------------ - added an annotation editor - solved a bug that could cause an errormessage "can not open file for reading" - solved a bug that could cause a false positive when checking the EDF-header of an EDFplus file (patientfield) version 1.17 november 4, 2009 ------------ - solved a bug in load_montage_dialog.cpp that caused a crash when loading a montage and a label was not found version 1.16 october 28, 2009 ------------ - solved a bug in the BDF+ to EDF+ converter - solved a bug in the XML parser - solved a memoryleak when using filters - solved some minor bugs - added a floating ruler - made some minor cosmetic changes - updated Qt to version 4.5.3 version 1.15 june 18, 2009 ----------- - solved a bug that could cause a crash when using crosshairs version 1.14 april 27, 2009 ----------- - solved a bug & optimized the code in the BDF to EDF converter - updated Qt to version 4.5.1 version 1.13 april 20, 2009 ----------- - added a BDF(+) to EDF(+) converter version 1.12 april 2, 2009 ----------- - bugfix release, solved a crash when removing a signal or a filter version 1.11 march 31, 2009 ----------- - added an EDF+D to EDF+C converter, it can convert discontinues files to continues files (interrupted recordings to un-interrupted recordings), can be used for BDF+D files as well - added an Emsa (*.PLG) EEG to EDF+ format converter - updated Qt to version 4.5.0 which has better GTK-style support when Gnome is used version 1.10 februari 13, 2009 ----------- - solved a bug that generated a false "read error" message when using filters at the start of the file (this bug appeared in version 1.09) version 1.09 februari 11, 2009 ----------- - solved a bug in the "Print to EDF/BDF" tools which could cause a crash - solved compilerwarnings in GCC 4.3.2 (warn_unused_result) version 1.08 december 15, 2008 ----------- - added a slider for navigating - solved a bug in the BDF+ compatibility checker - disabled the possibility to open discontinuous files (interrupted recordings) because of technical reasons version 1.07 november 5, 2008 ----------- - improved speed when a long displaytime is used - added support for the BDF+ format. Read the details here. - solved some minor bugs version 1.06 october 23, 2008 ----------- - solved a minor issue with the built-in EDF-checker - updated Qt to 4.4.3 version 1.05 september 17, 2008 ----------- - added a Finometer (Beatscope) to EDF format converter. (Finometer is a non-invasive stationary blood measurement and beat to beat haemodynamic monitoring system made by Finapres Medical Systems) read the documentation for the details. - solved a bug that causes a crash when a file was opened via the cmd-line with an unknown extension. - updated Qt to 4.4.1 Version 1.04 may 2, 2008 ----------- - added an ASCII to EDF format converter Version 1.03 march 31, 2008 ----------- - improved printing resolution - solved an issue with printermargins and fonts thanks to new printerframework in Qt 4.4.x - added option to "print" to an EDF or BDF file now you can extract one or more signals and write it to a new EDF file or you can combine signals from several files into one new EDF file printing to a BDF file is supported as well read the manual for the details - added option user defined displaytime (pagetime) - added option jump to end of recording - dropped the maximum datarecordblocksize of 61440 bytes requirement for EDF+ files from now on EDFbrowser will accept EDF+ files with larger blocksizes Version 1.02 februari 11, 2008 ----------- - solved a bug that potentially could crash the program when opening EDF+ files with a durationfield in annotations Version 1.01 januari 21, 2008 ----------- - solved two bugs that could create errors in timesyncing between multiple files - added support for large files (>2.1GB) - updated Qt to version 4.3.3 Version 1.00 januari 8, 2008 ----------- - Initial release. edfbrowser_153_source/PaxHeaders.2978/reduce_signals.cpp0000644000175000001440000000013212251654530021642 xustar000000000000000030 mtime=1386699096.479032511 30 atime=1386699096.478032517 30 ctime=1386699096.479032511 edfbrowser_153_source/reduce_signals.cpp0000644000175000001440000010067612251654530021405 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "reduce_signals.h" #if defined(__APPLE__) || defined(__MACH__) || defined(__APPLE_CC__) #define fopeno fopen #else #define fseeko fseeko64 #define ftello ftello64 #define fopeno fopen64 #endif UI_ReduceSignalsWindow::UI_ReduceSignalsWindow(QWidget *w_parent) { mainwindow = (UI_Mainwindow *)w_parent; recent_savedir = mainwindow->recent_savedir; myobjectDialog = new QDialog; myobjectDialog->setMinimumSize(665, 526); myobjectDialog->setMaximumSize(665, 526); myobjectDialog->setWindowTitle("Reduce signals and/or duration"); myobjectDialog->setModal(TRUE); myobjectDialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); label1 = new QLabel(myobjectDialog); label1->setGeometry(20, 20, 635, 25); label2 = new QLabel(myobjectDialog); label2->setGeometry(435, 307, 100, 25); label2->setText("from datarecord"); label2->setEnabled(FALSE); label3 = new QLabel(myobjectDialog); label3->setGeometry(435, 372, 100, 25); label3->setText("to datarecord"); label3->setEnabled(FALSE); label4 = new QLabel(myobjectDialog); label4->setGeometry(555, 332, 100, 25); label4->setEnabled(FALSE); label5 = new QLabel(myobjectDialog); label5->setGeometry(555, 397, 100, 25); label5->setEnabled(FALSE); radioButton1 = new QRadioButton("whole duration", myobjectDialog); radioButton1->setGeometry(435, 247, 100, 25); radioButton1->setChecked(TRUE); radioButton1->setEnabled(FALSE); radioButton2 = new QRadioButton("selection", myobjectDialog); radioButton2->setGeometry(435, 272, 100, 25); radioButton2->setEnabled(FALSE); spinBox1 = new QSpinBox(myobjectDialog); spinBox1->setGeometry(435, 332, 100, 25); spinBox1->setRange(1, 2147483647); spinBox1->setValue(1); spinBox1->setEnabled(FALSE); spinBox2 = new QSpinBox(myobjectDialog); spinBox2->setGeometry(435, 397, 100, 25); spinBox2->setRange(1, 2147483647); spinBox2->setValue(2147483647); spinBox2->setEnabled(FALSE); spinBox3 = new QSpinBox(myobjectDialog); spinBox3->setGeometry(545, 170, 100, 25); spinBox3->setRange(1, 100000); spinBox3->setValue(1); spinBox3->setEnabled(FALSE); SignalsTablewidget = new QTableWidget(myobjectDialog); SignalsTablewidget->setGeometry(20, 66, 355, 380); SignalsTablewidget->setSelectionMode(QAbstractItemView::NoSelection); SignalsTablewidget->setColumnCount(2); SignalsTablewidget->setColumnWidth(0, 180); SignalsTablewidget->setColumnWidth(1, 130); QStringList horizontallabels; horizontallabels += "Label"; horizontallabels += "Samplerate divider"; SignalsTablewidget->setHorizontalHeaderLabels(horizontallabels); pushButton1 = new QPushButton(myobjectDialog); pushButton1->setGeometry(QRect(20, 476, 100, 25)); pushButton1->setText("Select File"); pushButton2 = new QPushButton(myobjectDialog); pushButton2->setGeometry(545, 476, 100, 25); pushButton2->setText("Close"); pushButton3 = new QPushButton(myobjectDialog); pushButton3->setGeometry(200, 476, 100, 25); pushButton3->setText("Reduce"); pushButton3->setEnabled(FALSE); pushButton4 = new QPushButton(myobjectDialog); pushButton4->setGeometry(395, 66, 140, 25); pushButton4->setText("Select all signals"); pushButton4->setEnabled(FALSE); pushButton5 = new QPushButton(myobjectDialog); pushButton5->setGeometry(395, 118, 140, 25); pushButton5->setText("Deselect all signals"); pushButton5->setEnabled(FALSE); pushButton6 = new QPushButton(myobjectDialog); pushButton6->setGeometry(395, 170, 140, 25); pushButton6->setText("Set samplerate divider:"); pushButton6->setEnabled(FALSE); QObject::connect(pushButton1, SIGNAL(clicked()), this, SLOT(SelectFileButton())); QObject::connect(pushButton2, SIGNAL(clicked()), myobjectDialog, SLOT(close())); QObject::connect(pushButton3, SIGNAL(clicked()), this, SLOT(StartConversion())); QObject::connect(pushButton4, SIGNAL(clicked()), this, SLOT(Select_all_signals())); QObject::connect(pushButton5, SIGNAL(clicked()), this, SLOT(Deselect_all_signals())); QObject::connect(pushButton6, SIGNAL(clicked()), this, SLOT(Set_SRdivider_all_signals())); QObject::connect(spinBox1, SIGNAL(valueChanged(int)), this, SLOT(spinBox1changed(int))); QObject::connect(spinBox2, SIGNAL(valueChanged(int)), this, SLOT(spinBox2changed(int))); QObject::connect(radioButton1, SIGNAL(toggled(bool)), this, SLOT(radioButton1Toggled(bool))); QObject::connect(radioButton2, SIGNAL(toggled(bool)), this, SLOT(radioButton2Toggled(bool))); edfhdr = NULL; inputfile = NULL; outputfile = NULL; file_num = -1; inputpath[0] = 0; myobjectDialog->exec(); } void UI_ReduceSignalsWindow::spinBox1changed(int value) { long long seconds, milliSec; int days; char scratchpad[256]; QObject::disconnect(spinBox2, SIGNAL(valueChanged(int)), this, SLOT(spinBox2changed(int))); spinBox2->setMinimum(value); QObject::connect(spinBox2, SIGNAL(valueChanged(int)), this, SLOT(spinBox2changed(int))); if(edfhdr == NULL) { return; } days = (int)((((value - 1) * edfhdr->long_data_record_duration) / TIME_DIMENSION) / 86400LL); seconds = ((value - 1) * edfhdr->long_data_record_duration) / TIME_DIMENSION; if(seconds < 0) { seconds = 0; } seconds %= 86400LL; milliSec = ((value - 1) * edfhdr->long_data_record_duration) % TIME_DIMENSION; milliSec /= 10000LL; if(days) { sprintf(scratchpad, "%id %i:%02i:%02i.%03i", days, (int)(seconds / 3600), (int)((seconds % 3600) / 60), (int)(seconds % 60), (int)milliSec); } else { sprintf(scratchpad, "%i:%02i:%02i.%03i", (int)(seconds / 3600), (int)((seconds % 3600) / 60), (int)(seconds % 60), (int)milliSec); } label4->setText(scratchpad); } void UI_ReduceSignalsWindow::spinBox2changed(int value) { long long seconds, milliSec; int days; char scratchpad[256]; QObject::disconnect(spinBox1, SIGNAL(valueChanged(int)), this, SLOT(spinBox1changed(int))); spinBox1->setMaximum(value); QObject::connect(spinBox1, SIGNAL(valueChanged(int)), this, SLOT(spinBox1changed(int))); if(edfhdr == NULL) { return; } days = (int)(((value * edfhdr->long_data_record_duration) / TIME_DIMENSION) / 86400LL); seconds = (value * edfhdr->long_data_record_duration) / TIME_DIMENSION; seconds %= 86400LL; milliSec = (value * edfhdr->long_data_record_duration) % TIME_DIMENSION; milliSec /= 10000LL; if(days) { sprintf(scratchpad, "%id %i:%02i:%02i.%03i", days, (int)(seconds / 3600), (int)((seconds % 3600) / 60), (int)(seconds % 60), (int)milliSec); } else { sprintf(scratchpad, "%i:%02i:%02i.%03i", (int)(seconds / 3600), (int)((seconds % 3600) / 60), (int)(seconds % 60), (int)milliSec); } label5->setText(scratchpad); } void UI_ReduceSignalsWindow::radioButton1Toggled(bool checked) { long long seconds, milliSec; int days; char scratchpad[256]; if(checked == TRUE) { spinBox1->setEnabled(FALSE); spinBox2->setEnabled(FALSE); label2->setEnabled(FALSE); label3->setEnabled(FALSE); label4->setEnabled(FALSE); label5->setEnabled(FALSE); if(edfhdr == NULL) { return; } spinBox1->setValue(1); spinBox2->setMaximum(edfhdr->datarecords); spinBox2->setValue(edfhdr->datarecords); spinBox1->setMaximum(edfhdr->datarecords); days = (int)(((edfhdr->datarecords * edfhdr->long_data_record_duration) / TIME_DIMENSION) / 86400LL); seconds = (edfhdr->datarecords * edfhdr->long_data_record_duration) / TIME_DIMENSION; seconds %= 86400LL; milliSec = (edfhdr->datarecords * edfhdr->long_data_record_duration) % TIME_DIMENSION; milliSec /= 10000LL; if(days > 0) { label4->setText("0d 0:00:00.000"); sprintf(scratchpad, "%id %i:%02i:%02i.%03i", days, (int)(seconds / 3600), (int)((seconds % 3600) / 60), (int)(seconds % 60), (int)milliSec); } else { label4->setText("0:00:00.000"); sprintf(scratchpad, "%i:%02i:%02i.%03i", (int)(seconds / 3600), (int)((seconds % 3600) / 60), (int)(seconds % 60), (int)milliSec); } label5->setText(scratchpad); } } void UI_ReduceSignalsWindow::radioButton2Toggled(bool checked) { if(checked == TRUE) { spinBox1->setEnabled(TRUE); spinBox2->setEnabled(TRUE); label2->setEnabled(TRUE); label3->setEnabled(TRUE); label4->setEnabled(TRUE); label5->setEnabled(TRUE); } } void UI_ReduceSignalsWindow::Select_all_signals() { int i; if(edfhdr==NULL) { return; } for(i=0; iedfsignals; i++) { if(!edfhdr->edfparam[i].annotation) { ((QCheckBox *)(SignalsTablewidget->cellWidget(i, 0)))->setCheckState(Qt::Checked); } } } void UI_ReduceSignalsWindow::Deselect_all_signals() { int i; if(edfhdr==NULL) { return; } for(i=0; iedfsignals; i++) { if(!edfhdr->edfparam[i].annotation) { ((QCheckBox *)(SignalsTablewidget->cellWidget(i, 0)))->setCheckState(Qt::Unchecked); } } } void UI_ReduceSignalsWindow::Set_SRdivider_all_signals() { int i, j, sr, idx; sr = spinBox3->value(); for(i=0; iedfsignals; i++) { if(edfhdr->edfparam[i].annotation) { continue; } idx = 0; for(j=1; j<=edfhdr->edfparam[i].smp_per_record; j++) { if(!(edfhdr->edfparam[i].smp_per_record % j)) { if(j == sr) { if(idx < ((QComboBox *)(SignalsTablewidget->cellWidget(i, 1)))->count()) { ((QComboBox *)(SignalsTablewidget->cellWidget(i, 1)))->setCurrentIndex(idx); } break; } idx++; } } } } void UI_ReduceSignalsWindow::SelectFileButton() { int i, j, days; long long seconds, milliSec; char txt_string[2048], str[256]; label1->clear(); label4->clear(); label5->clear(); SignalsTablewidget->setRowCount(0); inputfile = NULL; outputfile = NULL; inputpath[0] = 0; edfhdr = NULL; file_num = -1; pushButton3->setEnabled(FALSE); pushButton4->setEnabled(FALSE); pushButton5->setEnabled(FALSE); pushButton6->setEnabled(FALSE); spinBox1->setEnabled(FALSE); spinBox2->setEnabled(FALSE); spinBox3->setEnabled(FALSE); radioButton1->setChecked(TRUE); radioButton1->setEnabled(FALSE); radioButton2->setEnabled(FALSE); label2->setEnabled(FALSE); label3->setEnabled(FALSE); label4->setEnabled(FALSE); label5->setEnabled(FALSE); UI_activeFileChooserWindow afchooser(&file_num, mainwindow); if(file_num < 0) { return; } edfhdr = mainwindow->edfheaderlist[file_num]; strcpy(inputpath, edfhdr->filename); inputfile = edfhdr->file_hdl; if(inputfile==NULL) { snprintf(txt_string, 2048, "Can not open file %s for reading.", inputpath); QMessageBox messagewindow(QMessageBox::Critical, "Error", QString::fromLocal8Bit(txt_string)); messagewindow.exec(); inputpath[0] = 0; edfhdr = NULL; file_num = -1; return; } if(edfhdr->datarecords > 2147483647LL) { QMessageBox messagewindow(QMessageBox::Critical, "Failure", "This file contains more than 2147483647 datarecords.\n" "This tool can not handle more than 2147483647 datarecords."); messagewindow.exec(); inputfile = NULL; inputpath[0] = 0; edfhdr = NULL; file_num = -1; return; } /***************** load signalproperties ******************************/ label1->setText(inputpath); SignalsTablewidget->setRowCount(edfhdr->edfsignals); for(i=0; iedfsignals; i++) { SignalsTablewidget->setRowHeight(i, 20); SignalsTablewidget->setCellWidget(i, 0, new QCheckBox(edfhdr->edfparam[i].label)); ((QCheckBox *)(SignalsTablewidget->cellWidget(i, 0)))->setTristate(FALSE); ((QCheckBox *)(SignalsTablewidget->cellWidget(i, 0)))->setCheckState(Qt::Checked); if(edfhdr->edfparam[i].annotation) { ((QCheckBox *)(SignalsTablewidget->cellWidget(i, 0)))->setEnabled(FALSE); } if(!(edfhdr->edfparam[i].annotation)) { SignalsTablewidget->setCellWidget(i, 1, new QComboBox); ((QComboBox *)(SignalsTablewidget->cellWidget(i, 1)))->setEditable(FALSE); for(j=1; j<=edfhdr->edfparam[i].smp_per_record; j++) { if(!(edfhdr->edfparam[i].smp_per_record % j)) { snprintf(str, 256, "%i (%f", j, ((double)(edfhdr->edfparam[i].smp_per_record / j)) / edfhdr->data_record_duration); remove_trailing_zeros(str); strcat(str, " Hz)"); ((QComboBox *)(SignalsTablewidget->cellWidget(i, 1)))->addItem(str, QVariant(j)); } } } } pushButton3->setEnabled(TRUE); pushButton4->setEnabled(TRUE); pushButton5->setEnabled(TRUE); pushButton6->setEnabled(TRUE); spinBox1->setValue(1); spinBox2->setMaximum(edfhdr->datarecords); spinBox2->setValue(edfhdr->datarecords); spinBox1->setMaximum(edfhdr->datarecords); spinBox3->setEnabled(TRUE); radioButton1->setEnabled(TRUE); radioButton2->setEnabled(TRUE); label4->setText("0:00:00.000"); days = (int)(((edfhdr->datarecords * edfhdr->long_data_record_duration) / TIME_DIMENSION) / 86400LL); seconds = (edfhdr->datarecords * edfhdr->long_data_record_duration) / TIME_DIMENSION; seconds %= 86400LL; milliSec = (edfhdr->datarecords * edfhdr->long_data_record_duration) % TIME_DIMENSION; milliSec /= 10000LL; if(days) { sprintf(txt_string, "%id %i:%02i:%02i.%03i", days, (int)(seconds / 3600), (int)((seconds % 3600) / 60), (int)(seconds % 60), (int)milliSec); } else { sprintf(txt_string, "%i:%02i:%02i.%03i", (int)(seconds / 3600), (int)((seconds % 3600) / 60), (int)(seconds % 60), (int)milliSec); } label5->setText(txt_string); } void UI_ReduceSignalsWindow::StartConversion() { int i, j, k, 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, 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); 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; 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; iedfsignals; 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; } /////////////////////////////////////////////////////////////////// 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_2; } 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_2; } outputfile = fopeno(outputpath, "wb"); if(outputfile==NULL) { showpopupmessage("Error", "Can not open outputfile for writing."); goto END_2; } 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_3; } 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_3; } 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; iedfparam[signalslist[i]].label); } if(edfhdr->edfplus) { fprintf(outputfile, "EDF Annotations "); } if(edfhdr->bdfplus) { fprintf(outputfile, "BDF Annotations "); } for(i=0; iedfparam[signalslist[i]].transducer); } if(edfhdr->edfplus || edfhdr->bdfplus) { for(i=0; i<80; i++) { fputc(' ', outputfile); } } for(i=0; iedfparam[signalslist[i]].physdimension); } if(edfhdr->edfplus || edfhdr->bdfplus) { for(i=0; i<8; i++) { fputc(' ', outputfile); } } for(i=0; iedfparam[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; iedfparam[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; iedfparam[signalslist[i]].dig_min); } if(edfhdr->edfplus) { fprintf(outputfile, "-32768 "); } if(edfhdr->bdfplus) { fprintf(outputfile, "-8388608"); } for(i=0; iedfparam[signalslist[i]].dig_max); } if(edfhdr->edfplus) { fprintf(outputfile, "32767 "); } if(edfhdr->bdfplus) { fprintf(outputfile, "8388607 "); } for(i=0; iedfparam[signalslist[i]].prefilter); } if(edfhdr->edfplus || edfhdr->bdfplus) { for(i=0; i<80; i++) { fputc(' ', outputfile); } } for(i=0; iedfparam[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_processedprocessEvents(); if(progress.wasCanceled() == TRUE) { goto END_3; } } if(fread(readbuf, edfhdr->recordsize, 1, inputfile) != 1) { progress.reset(); showpopupmessage("Error", "Read error (2)."); goto END_3; } if(edfhdr->edf) { for(i=0; iedfparam[signalslist[i]].smp_per_record; for(j=0; jedfparam[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_3; } } } else { smplrt = edfhdr->edfparam[signalslist[i]].smp_per_record / dividerlist[i]; for(j=0; jedfparam[signalslist[i]].buf_offset)) + (dividerlist[i] * j) + k); } tmp /= dividerlist[i]; fputc(tmp & 0xff, outputfile); if(fputc((tmp >> 8) & 0xff, outputfile)==EOF) { progress.reset(); showpopupmessage("Error", "Write error (4)."); goto END_3; } } } } } else { for(i=0; iedfparam[signalslist[i]].smp_per_record; for(j=0; jedfparam[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_3; } } } else { smplrt = edfhdr->edfparam[signalslist[i]].smp_per_record / dividerlist[i]; for(j=0; jedfparam[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; } 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_3; } } } } } 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; ionset / 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_3; } 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; klong_data_record_duration; } } progress.reset(); showpopupmessage("Ready", "Done."); END_3: fclose(outputfile); outputfile = NULL; END_2: if(readbuf != NULL) { free(readbuf); readbuf = NULL; } END_1: inputfile = NULL; inputpath[0] = 0; label1->clear(); label4->clear(); label5->clear(); file_num = -1; edfhdr = NULL; edfplus_annotation_delete_list(&root_new_annot_list); root_new_annot_list = NULL; SignalsTablewidget->setRowCount(0); } void UI_ReduceSignalsWindow::showpopupmessage(const char *str1, const char *str2) { UI_Messagewindow popupmessage(str1, str2); } edfbrowser_153_source/PaxHeaders.2978/unisens2edf.h0000644000175000001440000000013212251654530020545 xustar000000000000000030 mtime=1386699096.468032569 30 atime=1386699096.468032569 30 ctime=1386699096.468032569 edfbrowser_153_source/unisens2edf.h0000644000175000001440000000653212251654530020304 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef UI_UNISENS2EDFFORM_H #define UI_UNISENS2EDFFORM_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "xml.h" #include "edflib.h" #include "utils.h" class UI_UNISENS2EDFwindow : public QObject { Q_OBJECT public: UI_UNISENS2EDFwindow(char *recent_dir=NULL, char *save_dir=NULL); private: QTextEdit *textEdit1; QPushButton *pushButton1, *pushButton2; QDialog *myobjectDialog; char *recent_opendir, *recent_savedir, binfilename[MAXFILES][MAX_PATH_LENGTH], evtfilename[MAXFILES][MAX_PATH_LENGTH], physdim[MAXFILES][9], signallabel[MAXSIGNALS][17], str_timestampStart[32], str_measurementId[128], csv_sep[MAXFILES], csv_dec_sep[MAXFILES]; int straightbinary[MAXFILES], big_endian[MAXFILES], samplesize[MAXFILES], datatype[MAXFILES], sf[MAXFILES], csv_enc[MAXFILES], nedval_enc[MAXFILES], nedval_smpl[MAXFILES], nedval_value[MAXFILES][MAXSIGNALS], nedval_value2[MAXFILES][MAXSIGNALS], sf_less_1, sf_inv[MAXFILES], sf_divider, digmax[MAXFILES], digmin[MAXFILES], adcres[MAXFILES], datablocks[MAXFILES], edf_signals[MAXFILES], total_edf_signals, edf_signal_start[MAXFILES], max_datablocks, file_cnt, trig_file_cnt, buf1_offset[MAXFILES], buf2_offset[MAXFILES], buf1_freadsize[MAXFILES], char_encoding, bdf, evt_sf[MAXFILES], total_annotations, starttime_fraction; long long adczero[MAXFILES], baseline[MAXFILES]; double physmax[MAXFILES], physmin[MAXFILES], lsbval[MAXFILES]; FILE *binfile[MAXFILES]; int get_signalparameters_from_BIN_attributes(struct xml_handle *, int); int get_signalparameters_from_EVT_attributes(struct xml_handle *, int); int get_events_from_csv_files(int, int, const char *); int count_events_from_csv_files(int, const char *, int *); private slots: void SelectFileButton(); }; #endif edfbrowser_153_source/PaxHeaders.2978/LICENSE0000644000175000001440000000013212251654530017154 xustar000000000000000030 mtime=1386699096.506032369 30 atime=1386699096.506032369 30 ctime=1386699096.506032369 edfbrowser_153_source/LICENSE0000644000175000001440000003637212251654530016720 0ustar00novarausers00000000000000This is free software, it is experimental and available under the GPL License version 2. Despite this software is intend to be useful, there is no warranty, Use this software at your own risk! EDFbrowser may NOT be used in safety-critical applications, such as life-support medical systems. The author is NOT responsible for any consequences. For research and educational purpose only. GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS edfbrowser_153_source/PaxHeaders.2978/filtercurve.h0000644000175000001440000000013212251654530020652 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/filtercurve.h0000644000175000001440000000462512251654530020412 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef FILTERCURVE_H #define FILTERCURVE_H #include #include #include class FilterCurve: public QWidget { Q_OBJECT public: FilterCurve(QWidget *parent=0); QSize sizeHint() const {return minimumSizeHint(); } QSize minimumSizeHint() const {return QSize(30,10); } void setSignalColor1(QColor); void setSignalColor2(QColor); void setTraceWidth(int); void setBackgroundColor(QColor); void setRasterColor(QColor); void setMarkerColor(QColor); void setH_RasterSize(int); void setV_RasterSize(int); void drawCurve(double *, int, double, double); void drawCurve(double *, int, double, double, double *, int, double, double, int mrkr1 = 0, int mrkr2 = 0); public slots: protected: void paintEvent(QPaintEvent *); private: QColor SignalColor1, SignalColor2, BackgroundColor, RasterColor, MarkerColor; double max_value1, min_value1, *buf1, max_value2, min_value2, *buf2; int bufsize1, bufsize2, h_rastersize, v_rastersize, drawcurve_before_raster, tracewidth, marker_1, marker_2; }; #endif edfbrowser_153_source/PaxHeaders.2978/popup_messagewindow.h0000644000175000001440000000013212251654530022417 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/popup_messagewindow.h0000644000175000001440000000324712251654530022156 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef POPUP_MESSAGEFORM1_H #define POPUP_MESSAGEFORM1_H #include #include #include #include #include #include #include #include "global.h" class UI_Messagewindow : public QObject { Q_OBJECT public: UI_Messagewindow(const char *, const char *, const char *buttontxt = NULL, int timeout = 0); private: QDialog *MessageDialog; QLabel *Label1; QPushButton *pushButton1; }; #endif // POPUP_MESSAGEFORM1_H edfbrowser_153_source/PaxHeaders.2978/ecg_filter.h0000644000175000001440000000013212251654530020423 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/ecg_filter.h0000644000175000001440000001163512251654530020162 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef ecg_filter_INCLUDED #define ecg_filter_INCLUDED #include #include #include struct ecg_filter_settings{ int avgfilter_50_size; double *avgfilter_50_buf; int avgfilter_50_idx; double avgfilter_50_mean; double *avgfilter_50_buf_bu; int avgfilter_50_idx_bu; double avgfilter_50_mean_bu; int avgfilter_35_size; double *avgfilter_35_buf; int avgfilter_35_idx; double avgfilter_35_mean; double *avgfilter_35_buf_bu; int avgfilter_35_idx_bu; double avgfilter_35_mean_bu; int avgfilter_25_size; double *avgfilter_25_buf; int avgfilter_25_idx; double avgfilter_25_mean; double *avgfilter_25_buf_bu; int avgfilter_25_idx_bu; double avgfilter_25_mean_bu; double *SV; int SV_sz; int SV_idx; double SV_bu[3]; int SV_idx_bu; int runin; int runin_bu; int M_startslope; int M_endslope; int smpl_n; double M[5]; int M_idx; double M_avg; double drain; double top; double sf; double *F; int F_size; int F_idx; int F_wd; double F_value; double F_sf_factor; int R[5]; int R_idx; int R_avg; double R_value; int R_startslope; int R_endslope; double bpm; double bitvalue; int M_startslope_bu; int M_endslope_bu; int smpl_n_bu; double M_bu[5]; int M_idx_bu; double M_avg_bu; double drain_bu; double top_bu; double *F_bu; int F_idx_bu; double F_value_bu; int R_bu[5]; int R_idx_bu; int R_avg_bu; double R_value_bu; int R_startslope_bu; int R_endslope_bu; double bpm_bu; int bu_filled; double *stat_buf; long long *stat_smpl_buf; int stat_buf_idx; int sample_cntr; double T_peak_avg; double T_peak_avg_bu; }; struct ecg_filter_settings * create_ecg_filter(double, double, int); double run_ecg_filter(double, struct ecg_filter_settings *); void free_ecg_filter(struct ecg_filter_settings *); void ecg_filter_save_buf(struct ecg_filter_settings *); void ecg_filter_restore_buf(struct ecg_filter_settings *); void reset_ecg_filter(struct ecg_filter_settings *); int ecg_filter_get_beat_cnt(struct ecg_filter_settings *); long long * ecg_filter_get_onset_beatlist(struct ecg_filter_settings *); double * ecg_filter_get_interval_beatlist(struct ecg_filter_settings *); #endif edfbrowser_153_source/PaxHeaders.2978/utils.c0000644000175000001440000000013212251654530017453 xustar000000000000000030 mtime=1386699096.471032554 30 atime=1386699096.471032554 30 ctime=1386699096.471032554 edfbrowser_153_source/utils.c0000644000175000001440000004772612251654530017224 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "utils.h" /* removes extension including the dot */ void remove_extension_from_filename(char *str) { int i, len; len = strlen(str); if(len < 1) { return; } for(i=len-1; i>=0; i--) { if((str[i]=='/') || (str[i]=='\\')) { return; } if(str[i]=='.') { str[i] = 0; return; } } } /* size is size of destination, returns length of filename */ int get_filename_from_path(char *dest, const char *src, int size) { int i, len; if(size<1) { return(-1); } if(size<2) { dest[0] = 0; return(0); } len = strlen(src); if(len < 1) { dest[0] = 0; return(0); } for(i=len-1; i>=0; i--) { if((src[i]=='/') || (src[i]=='\\')) { break; } } i++; strncpy(dest, src + i, size); dest[size-1] = 0; return(strlen(dest)); } /* size is size of destination, returns length of directory */ /* last character of destination is not a slash! */ int get_directory_from_path(char *dest, const char *src, int size) { int i, len; if(size<1) { return(-1); } if(size<2) { dest[0] = 0; return(0); } len = strlen(src); if(len < 1) { dest[0] = 0; return(0); } for(i=len-1; i>=0; i--) { if((src[i]=='/') || (src[i]=='\\')) { break; } } strncpy(dest, src, size); if(i < size) { dest[i] = 0; } else { dest[size-1] = 0; } return(strlen(dest)); } void convert_trailing_zeros_to_spaces(char *str) { int i, j, len; len = strlen(str); for(i=0; i=0; j--) { if((str[j]!='.')&&(str[j]!='0')) { break; } if(str[j]=='.') { str[j] = ' '; break; } str[j] = ' '; } break; } } } void remove_trailing_spaces(char *str) { int i, len; len = strlen(str); for(i=(len-1); i>-1; i--) { if(str[i]!=' ') break; } str[i+1] = 0; } void remove_leading_spaces(char *str) { int i, diff, len; len = strlen(str); for(i=0; i '9')) { if(decimalzerofound) { if(str[i-decimalzerofound-1] == '.') { decimalzerofound++; } for(j=i; j<(len+1); j++) { str[j-decimalzerofound] = str[j]; } trailingzerofound = 1; break; } if(str[i] != '.') { numberfound = 0; dotfound = 0; decimalzerofound = 0; } } else { numberfound = 1; if(str[i] > '0') { decimalzerofound = 0; } } if((str[i] == '.') && numberfound) { dotfound = 1; } if((str[i] == '0') && dotfound) { decimalzerofound++; } } } if(decimalzerofound) { if(str[i-decimalzerofound-1] == '.') { decimalzerofound++; } for(j=i; j<(len+1); j++) { str[j-decimalzerofound] = str[j]; } } if(len > 1) { if(!((str[len - 2] < '0') || (str[i] > '9'))) { if(str[len - 1] == '.') { str[len - 1] = 0; } } } } void utf8_to_latin1(char *utf8_str) { int i, j, len; unsigned char *str; str = (unsigned char *)utf8_str; len = strlen(utf8_str); if(!len) { return; } j = 0; for(i=0; i 127) && (str[i] < 192))) { str[j++] = '.'; continue; } if(str[i] > 223) { str[j++] = 0; return; /* can only decode Latin-1 ! */ } if((str[i] & 224) == 192) /* found a two-byte sequence containing Latin-1, Greek, Cyrillic, Coptic, Armenian, Hebrew, etc. characters */ { if((i + 1) == len) { str[j++] = 0; return; } if((str[i] & 252) != 192) /* it's not a Latin-1 character */ { str[j++] = '.'; i++; continue; } if((str[i + 1] & 192) != 128) /* UTF-8 violation error */ { str[j++] = 0; return; } str[j] = str[i] << 6; str[j] += (str[i + 1] & 63); i++; j++; continue; } str[j++] = str[i]; } if(j126)&&(str[i]<160)) tmp_str[j] = '.'; if(str[i]>159) { if((len-j)<2) { tmp_str[j] = ' '; } else { tmp_str[j] = 192 + (str[i]>>6); j++; tmp_str[j] = 128 + (str[i]&63); } } j++; if(j>=len) break; } for(i=0; i31)&&(value<127)) { continue; } switch(value) { case 128 : str[i] = 'E'; break; case 130 : str[i] = ','; break; case 131 : str[i] = 'F'; break; case 132 : str[i] = '\"'; break; case 133 : str[i] = '.'; break; case 134 : str[i] = '+'; break; case 135 : str[i] = '+'; break; case 136 : str[i] = '^'; break; case 137 : str[i] = 'm'; break; case 138 : str[i] = 'S'; break; case 139 : str[i] = '<'; break; case 140 : str[i] = 'E'; break; case 142 : str[i] = 'Z'; break; case 145 : str[i] = '`'; break; case 146 : str[i] = '\''; break; case 147 : str[i] = '\"'; break; case 148 : str[i] = '\"'; break; case 149 : str[i] = '.'; break; case 150 : str[i] = '-'; break; case 151 : str[i] = '-'; break; case 152 : str[i] = '~'; break; case 154 : str[i] = 's'; break; case 155 : str[i] = '>'; break; case 156 : str[i] = 'e'; break; case 158 : str[i] = 'z'; break; case 159 : str[i] = 'Y'; break; case 171 : str[i] = '<'; break; case 180 : str[i] = '\''; break; case 181 : str[i] = 'u'; break; case 187 : str[i] = '>'; break; case 191 : str[i] = '\?'; break; case 192 : str[i] = 'A'; break; case 193 : str[i] = 'A'; break; case 194 : str[i] = 'A'; break; case 195 : str[i] = 'A'; break; case 196 : str[i] = 'A'; break; case 197 : str[i] = 'A'; break; case 198 : str[i] = 'E'; break; case 199 : str[i] = 'C'; break; case 200 : str[i] = 'E'; break; case 201 : str[i] = 'E'; break; case 202 : str[i] = 'E'; break; case 203 : str[i] = 'E'; break; case 204 : str[i] = 'I'; break; case 205 : str[i] = 'I'; break; case 206 : str[i] = 'I'; break; case 207 : str[i] = 'I'; break; case 208 : str[i] = 'D'; break; case 209 : str[i] = 'N'; break; case 210 : str[i] = 'O'; break; case 211 : str[i] = 'O'; break; case 212 : str[i] = 'O'; break; case 213 : str[i] = 'O'; break; case 214 : str[i] = 'O'; break; case 215 : str[i] = 'x'; break; case 216 : str[i] = 'O'; break; case 217 : str[i] = 'U'; break; case 218 : str[i] = 'U'; break; case 219 : str[i] = 'U'; break; case 220 : str[i] = 'U'; break; case 221 : str[i] = 'Y'; break; case 222 : str[i] = 'I'; break; case 223 : str[i] = 's'; break; case 224 : str[i] = 'a'; break; case 225 : str[i] = 'a'; break; case 226 : str[i] = 'a'; break; case 227 : str[i] = 'a'; break; case 228 : str[i] = 'a'; break; case 229 : str[i] = 'a'; break; case 230 : str[i] = 'e'; break; case 231 : str[i] = 'c'; break; case 232 : str[i] = 'e'; break; case 233 : str[i] = 'e'; break; case 234 : str[i] = 'e'; break; case 235 : str[i] = 'e'; break; case 236 : str[i] = 'i'; break; case 237 : str[i] = 'i'; break; case 238 : str[i] = 'i'; break; case 239 : str[i] = 'i'; break; case 240 : str[i] = 'd'; break; case 241 : str[i] = 'n'; break; case 242 : str[i] = 'o'; break; case 243 : str[i] = 'o'; break; case 244 : str[i] = 'o'; break; case 245 : str[i] = 'o'; break; case 246 : str[i] = 'o'; break; case 247 : str[i] = '-'; break; case 248 : str[i] = '0'; break; case 249 : str[i] = 'u'; break; case 250 : str[i] = 'u'; break; case 251 : str[i] = 'u'; break; case 252 : str[i] = 'u'; break; case 253 : str[i] = 'y'; break; case 254 : str[i] = 't'; break; case 255 : str[i] = 'y'; break; default : str[i] = ' '; break; } } } int antoi(const char *input_str, int len) { char str[1024]; strncpy(str, input_str, len); str[len] = 0; return(atoi_nonlocalized(str)); } /* minimum is the minimum digits that will be printed (minus sign not included), leading zero's will be added if necessary */ /* if sign is zero, only negative numbers will have the sign '-' character */ /* if sign is one, the sign '+' or '-' character will always be printed */ /* returns the amount of characters printed */ int fprint_int_number_nonlocalized(FILE *file, int q, int minimum, int sign) { int flag=0, z, i, j=0, base = 1000000000; if(minimum < 0) { minimum = 0; } if(minimum > 9) { flag = 1; } if(q < 0) { fputc('-', file); j++; q = -q; } else { if(sign) { fputc('+', file); j++; } } for(i=10; i; i--) { if(minimum == i) { flag = 1; } z = q / base; q %= base; if(z || flag) { fputc('0' + z, file); j++; flag = 1; } base /= 10; } if(!flag) { fputc('0', file); j++; } return(j); } /* minimum is the minimum digits that will be printed (minus sign not included), leading zero's will be added if necessary */ /* if sign is zero, only negative numbers will have the sign '-' character */ /* if sign is one, the sign '+' or '-' character will always be printed */ /* returns the amount of characters printed */ int fprint_ll_number_nonlocalized(FILE *file, long long q, int minimum, int sign) { int flag=0, z, i, j=0; long long base = 1000000000000000000LL; if(minimum < 0) { minimum = 0; } if(minimum > 18) { flag = 1; } if(q < 0LL) { fputc('-', file); j++; q = -q; } else { if(sign) { fputc('+', file); j++; } } for(i=19; i; i--) { if(minimum == i) { flag = 1; } z = q / base; q %= base; if(z || flag) { fputc('0' + z, file); j++; flag = 1; } base /= 10LL; } if(!flag) { fputc('0', file); j++; } return(j); } /* minimum is the minimum digits that will be printed (minus sign not included), leading zero's will be added if necessary */ /* if sign is zero, only negative numbers will have the sign '-' character */ /* if sign is one, the sign '+' or '-' character will always be printed */ /* returns the amount of characters printed */ int sprint_int_number_nonlocalized(char *str, int q, int minimum, int sign) { int flag=0, z, i, j=0, base = 1000000000; if(minimum < 0) { minimum = 0; } if(minimum > 9) { flag = 1; } if(q < 0) { str[j++] = '-'; q = -q; } else { if(sign) { str[j++] = '+'; } } for(i=10; i; i--) { if(minimum == i) { flag = 1; } z = q / base; q %= base; if(z || flag) { str[j++] = '0' + z; flag = 1; } base /= 10; } if(!flag) { str[j++] = '0'; } str[j] = 0; return(j); } /* minimum is the minimum digits that will be printed (minus sign not included), leading zero's will be added if necessary */ /* if sign is zero, only negative numbers will have the sign '-' character */ /* if sign is one, the sign '+' or '-' character will always be printed */ /* returns the amount of characters printed */ int sprint_ll_number_nonlocalized(char *str, long long q, int minimum, int sign) { int flag=0, z, i, j=0; long long base = 1000000000000000000LL; if(minimum < 0) { minimum = 0; } if(minimum > 18) { flag = 1; } if(q < 0LL) { str[j++] = '-'; q = -q; } else { if(sign) { str[j++] = '+'; } } for(i=19; i; i--) { if(minimum == i) { flag = 1; } z = q / base; q %= base; if(z || flag) { str[j++] = '0' + z; flag = 1; } base /= 10LL; } if(!flag) { str[j++] = '0'; } str[j] = 0; return(j); } int sprint_number_nonlocalized(char *str, double nr) { int flag=0, z, i, j=0, q, base = 1000000000; double var; q = (int)nr; var = nr - q; if(nr < 0.0) { str[j++] = '-'; if(q < 0) { q = -q; } } for(i=10; i; i--) { z = q / base; q %= base; if(z || flag) { str[j++] = '0' + z; flag = 1; } base /= 10; } if(!flag) { str[j++] = '0'; } base = 100000000; var *= (base * 10); q = (int)var; if(q < 0) { q = -q; } if(!q) { str[j] = 0; return(j); } str[j++] = '.'; for(i=9; i; i--) { z = q / base; q %= base; str[j++] = '0' + z; base /= 10; } str[j] = 0; j--; for(; j>0; j--) { if(str[j] == '0') { str[j] = 0; } else { j++; break; } } return(j); } double atof_nonlocalized(const char *str) { int i=0, dot_pos=-1, decimals=0, sign=1; double value, value2=0.0; value = atoi_nonlocalized(str); while(str[i] == ' ') { i++; } if((str[i] == '+') || (str[i] == '-')) { if(str[i] == '-') { sign = -1; } i++; } for(; ; i++) { if(str[i] == 0) { break; } if(((str[i] < '0') || (str[i] > '9')) && (str[i] != '.')) { break; } if(dot_pos >= 0) { if((str[i] >= '0') && (str[i] <= '9')) { decimals++; } else { break; } } if(str[i] == '.') { if(dot_pos < 0) { dot_pos = i; } } } if(decimals) { value2 = atoi_nonlocalized(str + dot_pos + 1) * sign; i = 1; while(decimals--) { i *= 10; } value2 /= i; } return(value + value2); } int atoi_nonlocalized(const char *str) { int i=0, value=0, sign=1; while(str[i] == ' ') { i++; } if((str[i] == '+') || (str[i] == '-')) { if(str[i] == '-') { sign = -1; } i++; } for( ; ; i++) { if(str[i] == 0) { break; } if((str[i] < '0') || (str[i] > '9')) { break; } value *= 10; value += (str[i] - '0'); } return(value * sign); } long long atoll_x(const char *str, int dimension) { int i, radix, negative=0; long long value=0LL; while(*str==' ') { str++; } if(*str=='-') { negative = 1; str++; } else { if(*str=='+') { str++; } } for(i=0; ; i++) { if(str[i]=='.') { str += (i + 1); break; } if((str[i]<'0') || (str[i]>'9')) { if(negative) { return(value * dimension * -1LL); } else { return(value * dimension); } } value *= 10LL; value += str[i] - '0'; } radix = 1; for(i=0; radix'9')) { break; } radix *= 10; value *= 10LL; value += str[i] - '0'; } if(negative) { return(value * (dimension / radix) * -1LL); } else { return(value * (dimension / radix)); } } int is_integer_number(char *str) { int i=0, l, hasspace = 0, hassign=0, digit=0; l = strlen(str); if(!l) return(1); if((str[0]=='+')||(str[0]=='-')) { hassign++; i++; } for(; i57)) { return(1); } else { if(hasspace) { return(1); } digit++; } } } if(digit) return(0); else return(1); } int is_number(char *str) { int i=0, l, hasspace = 0, hassign=0, digit=0, hasdot=0, hasexp=0; l = strlen(str); if(!l) return(1); if((str[0]=='+')||(str[0]=='-')) { hassign++; i++; } for(; i57))&&str[i]!='.') { return(1); } else { if(hasspace) { return(1); } if(str[i]=='.') { if(hasdot) return(1); hasdot++; } else { digit++; } } } } if(hasexp) { if(++i==l) { return(1); } if((str[i]=='+')||(str[i]=='-')) { hassign++; i++; } for(; i57)) { return(1); } else { if(hasspace) { return(1); } digit++; } } } } if(digit) return(0); else return(1); } void strntolower(char *s, int n) { int i; for(i=0; i 1000) value /=10; while(value < 100) value *=10; if(value > 670) { return(10); } else if(value > 300) { return(50); } else if(value > 135) { return(20); } else { return(10); } return(10); } edfbrowser_153_source/PaxHeaders.2978/header_editor.h0000644000175000001440000000013212251654530021116 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/header_editor.h0000644000175000001440000000627212251654530020656 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef UI_HEADEREDITORFORM_H #define UI_HEADEREDITORFORM_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "mainwindow.h" #include "popup_messagewindow.h" #include "utils.h" class UI_Mainwindow; class UI_headerEditorWindow : public QDialog { Q_OBJECT public: UI_headerEditorWindow(QWidget *parent); UI_Mainwindow *mainwindow; private: QTabWidget *tabholder; QWidget *tab1, *tab2; QTableWidget *signallist; QLabel *label1, *label2, *label3, *label4, *label5, *label6, *label7, *label8, *label9, *label11, *label12, *fileNameLabel, *charsleft1Label, *charsleft2Label, *startTimeDateLabel; QLineEdit *lineEdit1, *lineEdit2, *lineEdit3, *lineEdit4, *lineEdit5, *lineEdit6, *lineEdit7, *lineEdit8, *lineEdit9; QComboBox *comboBox1; QCheckBox *checkBox1; QDateEdit *dateEdit1; QPushButton *pushButton1, *pushButton2, *pushButton3; QDateTimeEdit *startTimeDate; int edfplus, bdfplus, edf, bdf, edfsignals, has_startdate, recordsize, datrecs; char path[MAX_PATH_LENGTH], *hdr; FILE *file; private slots: void open_file(); void save_hdr(); void read_header(); void closeEvent(QCloseEvent *); void calculate_chars_left_name(const QString &); void calculate_chars_left_recording(const QString &); }; #endif edfbrowser_153_source/PaxHeaders.2978/bi9800.cpp0000644000175000001440000000013212251654530017566 xustar000000000000000030 mtime=1386699096.477032522 30 atime=1386699096.477032522 30 ctime=1386699096.477032522 edfbrowser_153_source/bi9800.cpp0000644000175000001440000002752012251654530017325 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "bi9800.h" #if defined(__APPLE__) || defined(__MACH__) || defined(__APPLE_CC__) #define fopeno fopen #else #define fseeko fseeko64 #define ftello ftello64 #define fopeno fopen64 #endif UI_BI98002EDFwindow::UI_BI98002EDFwindow(char *recent_dir, char *save_dir) { recent_opendir = recent_dir; recent_savedir = save_dir; myobjectDialog = new QDialog; myobjectDialog->setMinimumSize(QSize(300, 75)); myobjectDialog->setMaximumSize(QSize(300, 75)); myobjectDialog->setWindowTitle("BI9800 to EDF+ converter"); myobjectDialog->setModal(TRUE); myobjectDialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); pushButton1 = new QPushButton(myobjectDialog); pushButton1->setGeometry(20, 30, 100, 25); pushButton1->setText("Select File"); pushButton2 = new QPushButton(myobjectDialog); pushButton2->setGeometry(180, 30, 100, 25); pushButton2->setText("Close"); QObject::connect(pushButton1, SIGNAL(clicked()), this, SLOT(SelectFileButton())); QObject::connect(pushButton2, SIGNAL(clicked()), myobjectDialog, SLOT(close())); myobjectDialog->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 recorddate."); 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(); UI_Messagewindow popuperror("Error", "Malloc error."); 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; iprocessEvents(); if(progress.wasCanceled() == TRUE) { break; } } n = fread(buf1, bufsize, 1, dcmfile); if(n != 1) { break; } for(i=0; i 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_BI98002EDFwindow::showpopupmessage(const char *str1, const char *str2) { UI_Messagewindow popupmessage(str1, str2); } edfbrowser_153_source/PaxHeaders.2978/bdf_triggers.cpp0000644000175000001440000000013212251654530021314 xustar000000000000000030 mtime=1386699096.477032522 30 atime=1386699096.477032522 30 ctime=1386699096.477032522 edfbrowser_153_source/bdf_triggers.cpp0000644000175000001440000001627112251654530021054 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "bdf_triggers.h" #if defined(__APPLE__) || defined(__MACH__) || defined(__APPLE_CC__) #define fopeno fopen #else #define fseeko fseeko64 #define ftello ftello64 #define fopeno fopen64 #endif int BDF_triggers::get_triggers(struct edfhdrblock *hdr, struct annotationblock **list) { int i, j, sf, status_signal=0, error, edfsignals, bufsize, jump_file, trigger_cnt, status[24]; char *buf; long long datarecords, long_data_record_duration, records_read, status_sample_duration, progress_steps; FILE *inputfile; struct annotationblock *annotation=NULL; struct annotationblock *annotlist; *list = NULL; annotlist = NULL; inputfile = hdr->file_hdl; edfsignals = hdr->edfsignals; datarecords = hdr->datarecords; long_data_record_duration = hdr->long_data_record_duration; if(edfsignals < 1) { return(0); } if(long_data_record_duration != TIME_DIMENSION) { return(0); } sf = hdr->edfparam[0].smp_per_record; for(i=1; iedfparam[i].smp_per_record != sf) { return(0); } } 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) { return(0); } for(i=0; iedfparam[i].label, "Status "))) { status_signal = i; break; } } if(i == edfsignals) { return(0); } bufsize = sf * 3; buf = (char *)calloc(1, bufsize); if(buf==NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Memory allocation error occurred when trying to read triggers.\n(buf)"); messagewindow.exec(); return(1); } if(fseeko(inputfile, ((long long)edfsignals + 1LL) * 256LL, SEEK_SET)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred when reading inputfile triggers."); messagewindow.exec(); free(buf); return(2); } jump_file = status_signal * sf * 3; status_sample_duration = TIME_DIMENSION / (long long)sf; trigger_cnt = 0; for(i=0; i<24; i++) { status[i] = 1; } QProgressDialog progress("Scanning file for triggers...", "Abort", 0, datarecords); progress.setWindowModality(Qt::WindowModal); progress.setMinimumDuration(200); progress_steps = datarecords / 100LL; if(progress_steps < 1LL) { progress_steps = 1LL; } for(records_read=0LL; records_readprocessEvents(); if(progress.wasCanceled() == TRUE) { break; } } if(trigger_cnt >= 100000) { break; } if(fseeko(inputfile, (long long)jump_file, SEEK_CUR)) { progress.reset(); QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred when reading inputfile triggers."); messagewindow.exec(); free(buf); return(2); } if(fread(buf, bufsize, 1, inputfile)!=1) { progress.reset(); QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred when reading inputfile triggers."); messagewindow.exec(); free(buf); return(2); } for(i=0; ifile_num = hdr->file_num; annotation->onset = (records_read * TIME_DIMENSION) + ((long long)(i / 3) * status_sample_duration); annotation->onset += hdr->starttime_offset; sprintf(annotation->annotation, "new epoch"); annotation->ident = (1 << ANNOT_ID_BS_TRIGGER); edfplus_annotation_add_item(&annotlist, annotation); trigger_cnt++; status[16] = 1; } } else { if(status[16]) // falling edge detected { status[16] = 0; } } for(j=0; j<16; j++) { if(*((unsigned short *)(buf + i)) & (1 << j)) { if(!status[j]) // rising edge detected { annotation = (struct annotationblock *)calloc(1, sizeof(struct annotationblock)); if(annotation == NULL) { progress.reset(); QMessageBox messagewindow(QMessageBox::Critical, "Error", "Malloc error (annotation)."); messagewindow.exec(); *list = annotlist; free(buf); return(1); } annotation->onset = (records_read * TIME_DIMENSION) + ((long long)(i / 3) * status_sample_duration); annotation->onset += hdr->starttime_offset; sprintf(annotation->annotation, "Trigger Input %i", j + 1); annotation->ident = (1 << ANNOT_ID_BS_TRIGGER); edfplus_annotation_add_item(&annotlist, annotation); trigger_cnt++; status[j] = 1; } } else { if(status[j]) // falling edge detected { status[j] = 0; } } } } } progress.reset(); *list = annotlist; free(buf); hdr->genuine_biosemi = 1; return(0); } edfbrowser_153_source/PaxHeaders.2978/edf_annotations.h0000644000175000001440000000013212251654530021473 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/edf_annotations.h0000644000175000001440000000333712251654530021232 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef EDF_ANNOTATIONS_H #define EDF_ANNOTATIONS_H #include #include #include #include #include #include #include "global.h" #include "popup_messagewindow.h" #include "edf_annot_list.h" class EDF_annotations { public: int get_annotations(int, struct edfhdrblock *, struct annotationblock **, int); private: int is_duration_number(char *); int is_onset_number(char *); long long get_long_time(char *); int check_device(char *); }; #endif // EDF_ANNOTATIONS_H edfbrowser_153_source/PaxHeaders.2978/colordialog.cpp0000644000175000001440000000013212251654530021151 xustar000000000000000030 mtime=1386699096.477032522 30 atime=1386699096.477032522 30 ctime=1386699096.477032522 edfbrowser_153_source/colordialog.cpp0000644000175000001440000002016712251654530020710 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "colordialog.h" UI_ColorMenuDialog::UI_ColorMenuDialog(int *newColor, QWidget *w_parent) { colormenu_dialog = new QDialog(w_parent); colormenu_dialog->setMinimumSize(QSize(105, 130)); colormenu_dialog->setMaximumSize(QSize(105, 130)); colormenu_dialog->setWindowTitle("Color"); colormenu_dialog->setModal(TRUE); colormenu_dialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); color = newColor; *color = -1; CloseButton = new QPushButton(colormenu_dialog); CloseButton->setGeometry(QRect(5, 105, 95, 20)); CloseButton->setText("Close"); ColorButton1 = new SpecialButton(colormenu_dialog); ColorButton1->setGeometry(QRect(5, 5, 20, 20)); ColorButton1->setColor(Qt::black); ColorButton2 = new SpecialButton(colormenu_dialog); ColorButton2->setGeometry(QRect(30, 5, 20, 20)); ColorButton2->setColor(Qt::red); ColorButton3 = new SpecialButton(colormenu_dialog); ColorButton3->setGeometry(QRect(55, 5, 20, 20)); ColorButton3->setColor(Qt::darkRed); ColorButton4 = new SpecialButton(colormenu_dialog); ColorButton4->setGeometry(QRect(80, 5, 20, 20)); ColorButton4->setColor(Qt::green); ColorButton5 = new SpecialButton(colormenu_dialog); ColorButton5->setGeometry(QRect(5, 30, 20, 20)); ColorButton5->setColor(Qt::darkGreen); ColorButton6 = new SpecialButton(colormenu_dialog); ColorButton6->setGeometry(QRect(30, 30, 20, 20)); ColorButton6->setColor(Qt::blue); ColorButton7 = new SpecialButton(colormenu_dialog); ColorButton7->setGeometry(QRect(55, 30, 20, 20)); ColorButton7->setColor(Qt::darkBlue); ColorButton8 = new SpecialButton(colormenu_dialog); ColorButton8->setGeometry(QRect(80, 30, 20, 20)); ColorButton8->setColor(Qt::cyan); ColorButton9 = new SpecialButton(colormenu_dialog); ColorButton9->setGeometry(QRect(5, 55, 20, 20)); ColorButton9->setColor(Qt::darkCyan); ColorButton10 = new SpecialButton(colormenu_dialog); ColorButton10->setGeometry(QRect(30, 55, 20, 20)); ColorButton10->setColor(Qt::magenta); ColorButton11 = new SpecialButton(colormenu_dialog); ColorButton11->setGeometry(QRect(55, 55, 20, 20)); ColorButton11->setColor(Qt::darkMagenta); ColorButton12 = new SpecialButton(colormenu_dialog); ColorButton12->setGeometry(QRect(80, 55, 20, 20)); ColorButton12->setColor(Qt::yellow); ColorButton13 = new SpecialButton(colormenu_dialog); ColorButton13->setGeometry(QRect(5, 80, 20, 20)); ColorButton13->setColor(Qt::darkYellow); ColorButton14 = new SpecialButton(colormenu_dialog); ColorButton14->setGeometry(QRect(30, 80, 20, 20)); ColorButton14->setColor(Qt::gray); ColorButton15 = new SpecialButton(colormenu_dialog); ColorButton15->setGeometry(QRect(55, 80, 20, 20)); ColorButton15->setColor(Qt::darkGray); ColorButton16 = new SpecialButton(colormenu_dialog); ColorButton16->setGeometry(QRect(80, 80, 20, 20)); ColorButton16->setColor(Qt::white); QObject::connect(CloseButton, SIGNAL(clicked()), colormenu_dialog, SLOT(close())); QObject::connect(ColorButton1, SIGNAL(clicked(SpecialButton *)), this, SLOT(ColorButton1_pressed(SpecialButton *))); QObject::connect(ColorButton2, SIGNAL(clicked(SpecialButton *)), this, SLOT(ColorButton2_pressed(SpecialButton *))); QObject::connect(ColorButton3, SIGNAL(clicked(SpecialButton *)), this, SLOT(ColorButton3_pressed(SpecialButton *))); QObject::connect(ColorButton4, SIGNAL(clicked(SpecialButton *)), this, SLOT(ColorButton4_pressed(SpecialButton *))); QObject::connect(ColorButton5, SIGNAL(clicked(SpecialButton *)), this, SLOT(ColorButton5_pressed(SpecialButton *))); QObject::connect(ColorButton6, SIGNAL(clicked(SpecialButton *)), this, SLOT(ColorButton6_pressed(SpecialButton *))); QObject::connect(ColorButton7, SIGNAL(clicked(SpecialButton *)), this, SLOT(ColorButton7_pressed(SpecialButton *))); QObject::connect(ColorButton8, SIGNAL(clicked(SpecialButton *)), this, SLOT(ColorButton8_pressed(SpecialButton *))); QObject::connect(ColorButton9, SIGNAL(clicked(SpecialButton *)), this, SLOT(ColorButton9_pressed(SpecialButton *))); QObject::connect(ColorButton10, SIGNAL(clicked(SpecialButton *)), this, SLOT(ColorButton10_pressed(SpecialButton *))); QObject::connect(ColorButton11, SIGNAL(clicked(SpecialButton *)), this, SLOT(ColorButton11_pressed(SpecialButton *))); QObject::connect(ColorButton12, SIGNAL(clicked(SpecialButton *)), this, SLOT(ColorButton12_pressed(SpecialButton *))); QObject::connect(ColorButton13, SIGNAL(clicked(SpecialButton *)), this, SLOT(ColorButton13_pressed(SpecialButton *))); QObject::connect(ColorButton14, SIGNAL(clicked(SpecialButton *)), this, SLOT(ColorButton14_pressed(SpecialButton *))); QObject::connect(ColorButton15, SIGNAL(clicked(SpecialButton *)), this, SLOT(ColorButton15_pressed(SpecialButton *))); QObject::connect(ColorButton16, SIGNAL(clicked(SpecialButton *)), this, SLOT(ColorButton16_pressed(SpecialButton *))); colormenu_dialog->exec(); } void UI_ColorMenuDialog::ColorButton1_pressed(SpecialButton *) { *color = Qt::black; colormenu_dialog->close(); } void UI_ColorMenuDialog::ColorButton2_pressed(SpecialButton *) { *color = Qt::red; colormenu_dialog->close(); } void UI_ColorMenuDialog::ColorButton3_pressed(SpecialButton *) { *color = Qt::darkRed; } void UI_ColorMenuDialog::ColorButton4_pressed(SpecialButton *) { *color = Qt::green; colormenu_dialog->close(); } void UI_ColorMenuDialog::ColorButton5_pressed(SpecialButton *) { *color = Qt::darkGreen; colormenu_dialog->close(); } void UI_ColorMenuDialog::ColorButton6_pressed(SpecialButton *) { *color = Qt::blue; colormenu_dialog->close(); } void UI_ColorMenuDialog::ColorButton7_pressed(SpecialButton *) { *color = Qt::darkBlue; colormenu_dialog->close(); } void UI_ColorMenuDialog::ColorButton8_pressed(SpecialButton *) { *color = Qt::cyan; colormenu_dialog->close(); } void UI_ColorMenuDialog::ColorButton9_pressed(SpecialButton *) { *color = Qt::darkCyan; colormenu_dialog->close(); } void UI_ColorMenuDialog::ColorButton10_pressed(SpecialButton *) { *color = Qt::magenta; colormenu_dialog->close(); } void UI_ColorMenuDialog::ColorButton11_pressed(SpecialButton *) { *color = Qt::darkMagenta; colormenu_dialog->close(); } void UI_ColorMenuDialog::ColorButton12_pressed(SpecialButton *) { *color = Qt::yellow; colormenu_dialog->close(); } void UI_ColorMenuDialog::ColorButton13_pressed(SpecialButton *) { *color = Qt::darkYellow; colormenu_dialog->close(); } void UI_ColorMenuDialog::ColorButton14_pressed(SpecialButton *) { *color = Qt::gray; colormenu_dialog->close(); } void UI_ColorMenuDialog::ColorButton15_pressed(SpecialButton *) { *color = Qt::darkGray; colormenu_dialog->close(); } void UI_ColorMenuDialog::ColorButton16_pressed(SpecialButton *) { *color = Qt::white; colormenu_dialog->close(); } edfbrowser_153_source/PaxHeaders.2978/fino2edf.h0000644000175000001440000000013212251654530020014 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/fino2edf.h0000644000175000001440000000434712251654530017555 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef UI_FINO2EDFFORM_H #define UI_FINO2EDFFORM_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "popup_messagewindow.h" #include "utils.h" #define MAX_SIGNALS 32 class UI_FINO2EDFwindow : public QObject { Q_OBJECT public: UI_FINO2EDFwindow(char *recent_dir=NULL, char *save_dir=NULL); private: QDialog *myobjectDialog; QPushButton *pushButton1, *pushButton2; QLabel *PatientnameLabel, *RecordingLabel, *DatetimeLabel; QLineEdit *PatientnameLineEdit, *RecordingLineEdit; QDateTimeEdit *StartDatetimeedit; char *recent_opendir, *recent_savedir; void enable_widgets(bool); private slots: void SelectFileButton(); }; #endif edfbrowser_153_source/PaxHeaders.2978/bi9800.h0000644000175000001440000000013212251654530017233 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/bi9800.h0000644000175000001440000000375712251654530017000 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef UI_BI98002EDFFORM_H #define UI_BI98002EDFFORM_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "popup_messagewindow.h" #include "edflib.h" #include "utils.h" class UI_BI98002EDFwindow : public QObject { Q_OBJECT public: UI_BI98002EDFwindow(char *recent_dir=NULL, char *save_dir=NULL); private: QPushButton *pushButton1, *pushButton2; QDialog *myobjectDialog; char *recent_opendir, *recent_savedir; void showpopupmessage(const char *, const char *); private slots: void SelectFileButton(); }; #endif edfbrowser_153_source/PaxHeaders.2978/third_party0000644000175000001440000000013212251654530020423 xustar000000000000000030 mtime=1386699096.463032596 30 atime=1386699096.463032596 30 ctime=1386699096.463032596 edfbrowser_153_source/third_party/0000755000175000001440000000000012251654530020231 5ustar00novarausers00000000000000edfbrowser_153_source/third_party/PaxHeaders.2978/kiss_fft0000644000175000001440000000013212251654530022233 xustar000000000000000030 mtime=1386699096.463032596 30 atime=1386699096.463032596 30 ctime=1386699096.463032596 edfbrowser_153_source/third_party/kiss_fft/0000755000175000001440000000000012251654530022041 5ustar00novarausers00000000000000edfbrowser_153_source/third_party/kiss_fft/PaxHeaders.2978/kiss_fft.h0000644000175000001440000000013212251654530024271 xustar000000000000000030 mtime=1386699096.463032596 30 atime=1386699096.463032596 30 ctime=1386699096.463032596 edfbrowser_153_source/third_party/kiss_fft/kiss_fft.h0000644000175000001440000000632512251654530024030 0ustar00novarausers00000000000000#ifndef KISS_FFT_H #define KISS_FFT_H #include #include #include #include #ifdef __cplusplus extern "C" { #endif /* ATTENTION! If you would like a : -- a utility that will handle the caching of fft objects -- real-only (no imaginary time component ) FFT -- a multi-dimensional FFT -- a command-line utility to perform ffts -- a command-line utility to perform fast-convolution filtering Then see kfc.h kiss_fftr.h kiss_fftnd.h fftutil.c kiss_fastfir.c in the tools/ directory. */ #ifdef USE_SIMD # include # define kiss_fft_scalar __m128 #define KISS_FFT_MALLOC(nbytes) _mm_malloc(nbytes,16) #define KISS_FFT_FREE _mm_free #else #define KISS_FFT_MALLOC malloc #define KISS_FFT_FREE free #endif #ifdef FIXED_POINT #include # if (FIXED_POINT == 32) # define kiss_fft_scalar int32_t # else # define kiss_fft_scalar int16_t # endif #else # ifndef kiss_fft_scalar /* default is float */ # define kiss_fft_scalar double # endif #endif typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; typedef struct kiss_fft_state* kiss_fft_cfg; /* * kiss_fft_alloc * * Initialize a FFT (or IFFT) algorithm's cfg/state buffer. * * typical usage: kiss_fft_cfg mycfg=kiss_fft_alloc(1024,0,NULL,NULL); * * The return value from fft_alloc is a cfg buffer used internally * by the fft routine or NULL. * * If lenmem is NULL, then kiss_fft_alloc will allocate a cfg buffer using malloc. * The returned value should be free()d when done to avoid memory leaks. * * The state can be placed in a user supplied buffer 'mem': * If lenmem is not NULL and mem is not NULL and *lenmem is large enough, * then the function places the cfg in mem and the size used in *lenmem * and returns mem. * * If lenmem is not NULL and ( mem is NULL or *lenmem is not large enough), * then the function returns NULL and places the minimum cfg * buffer size in *lenmem. * */ kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem); /* * kiss_fft(cfg,in_out_buf) * * Perform an FFT on a complex input buffer. * for a forward FFT, * fin should be f[0] , f[1] , ... ,f[nfft-1] * fout will be F[0] , F[1] , ... ,F[nfft-1] * Note that each element is complex and can be accessed like f[k].r and f[k].i * */ void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout); /* A more generic version of the above function. It reads its input from every Nth sample. * */ void kiss_fft_stride(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int fin_stride); /* If kiss_fft_alloc allocated a buffer, it is one contiguous buffer and can be simply free()d when no longer needed*/ #define kiss_fft_free free /* Cleans up some memory that gets managed internally. Not necessary to call, but it might clean up your compiler output to call this before you exit. */ void kiss_fft_cleanup(void); /* * Returns the smallest integer k, such that k>=n and k has only "fast" factors (2,3,5) */ int kiss_fft_next_fast_size(int n); /* for real ffts, we need an even size */ #define kiss_fftr_next_fast_size_real(n) \ (kiss_fft_next_fast_size( ((n)+1)>>1)<<1) #ifdef __cplusplus } #endif #endif edfbrowser_153_source/third_party/kiss_fft/PaxHeaders.2978/kiss_fftr.h0000644000175000001440000000013212251654530024453 xustar000000000000000030 mtime=1386699096.463032596 30 atime=1386699096.463032596 30 ctime=1386699096.463032596 edfbrowser_153_source/third_party/kiss_fft/kiss_fftr.h0000644000175000001440000000153212251654530024205 0ustar00novarausers00000000000000#ifndef KISS_FTR_H #define KISS_FTR_H #include "kiss_fft.h" #ifdef __cplusplus extern "C" { #endif /* Real optimized version can save about 45% cpu time vs. complex fft of a real seq. */ typedef struct kiss_fftr_state *kiss_fftr_cfg; kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem, size_t * lenmem); /* nfft must be even If you don't care to allocate space, use mem = lenmem = NULL */ void kiss_fftr(kiss_fftr_cfg cfg,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata); /* input timedata has nfft scalar points output freqdata has nfft/2+1 complex points */ void kiss_fftri(kiss_fftr_cfg cfg,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata); /* input freqdata has nfft/2+1 complex points output timedata has nfft scalar points */ #define kiss_fftr_free free #ifdef __cplusplus } #endif #endif edfbrowser_153_source/third_party/kiss_fft/PaxHeaders.2978/_kiss_fft_guts.h0000644000175000001440000000013212251654530025472 xustar000000000000000030 mtime=1386699096.463032596 30 atime=1386699096.463032596 30 ctime=1386699096.463032596 edfbrowser_153_source/third_party/kiss_fft/_kiss_fft_guts.h0000644000175000001440000001324612251654530025231 0ustar00novarausers00000000000000/* Copyright (c) 2003-2010, Mark Borgerding All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* kiss_fft.h defines kiss_fft_scalar as either short or a float type and defines typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; */ #include "kiss_fft.h" #include #define MAXFACTORS 32 /* e.g. an fft of length 128 has 4 factors as far as kissfft is concerned 4*4*4*2 */ struct kiss_fft_state{ int nfft; int inverse; int factors[2*MAXFACTORS]; kiss_fft_cpx twiddles[1]; }; /* Explanation of macros dealing with complex math: C_MUL(m,a,b) : m = a*b C_FIXDIV( c , div ) : if a fixed point impl., c /= div. noop otherwise C_SUB( res, a,b) : res = a - b C_SUBFROM( res , a) : res -= a C_ADDTO( res , a) : res += a * */ #ifdef FIXED_POINT #if (FIXED_POINT==32) # define FRACBITS 31 # define SAMPPROD int64_t #define SAMP_MAX 2147483647 #else # define FRACBITS 15 # define SAMPPROD int32_t #define SAMP_MAX 32767 #endif #define SAMP_MIN -SAMP_MAX #if defined(CHECK_OVERFLOW) # define CHECK_OVERFLOW_OP(a,op,b) \ if ( (SAMPPROD)(a) op (SAMPPROD)(b) > SAMP_MAX || (SAMPPROD)(a) op (SAMPPROD)(b) < SAMP_MIN ) { \ fprintf(stderr,"WARNING:overflow @ " __FILE__ "(%d): (%d " #op" %d) = %ld\n",__LINE__,(a),(b),(SAMPPROD)(a) op (SAMPPROD)(b) ); } #endif # define smul(a,b) ( (SAMPPROD)(a)*(b) ) # define sround( x ) (kiss_fft_scalar)( ( (x) + (1<<(FRACBITS-1)) ) >> FRACBITS ) # define S_MUL(a,b) sround( smul(a,b) ) # define C_MUL(m,a,b) \ do{ (m).r = sround( smul((a).r,(b).r) - smul((a).i,(b).i) ); \ (m).i = sround( smul((a).r,(b).i) + smul((a).i,(b).r) ); }while(0) # define DIVSCALAR(x,k) \ (x) = sround( smul( x, SAMP_MAX/k ) ) # define C_FIXDIV(c,div) \ do { DIVSCALAR( (c).r , div); \ DIVSCALAR( (c).i , div); }while (0) # define C_MULBYSCALAR( c, s ) \ do{ (c).r = sround( smul( (c).r , s ) ) ;\ (c).i = sround( smul( (c).i , s ) ) ; }while(0) #else /* not FIXED_POINT*/ # define S_MUL(a,b) ( (a)*(b) ) #define C_MUL(m,a,b) \ do{ (m).r = (a).r*(b).r - (a).i*(b).i;\ (m).i = (a).r*(b).i + (a).i*(b).r; }while(0) # define C_FIXDIV(c,div) /* NOOP */ # define C_MULBYSCALAR( c, s ) \ do{ (c).r *= (s);\ (c).i *= (s); }while(0) #endif #ifndef CHECK_OVERFLOW_OP # define CHECK_OVERFLOW_OP(a,op,b) /* noop */ #endif #define C_ADD( res, a,b)\ do { \ CHECK_OVERFLOW_OP((a).r,+,(b).r)\ CHECK_OVERFLOW_OP((a).i,+,(b).i)\ (res).r=(a).r+(b).r; (res).i=(a).i+(b).i; \ }while(0) #define C_SUB( res, a,b)\ do { \ CHECK_OVERFLOW_OP((a).r,-,(b).r)\ CHECK_OVERFLOW_OP((a).i,-,(b).i)\ (res).r=(a).r-(b).r; (res).i=(a).i-(b).i; \ }while(0) #define C_ADDTO( res , a)\ do { \ CHECK_OVERFLOW_OP((res).r,+,(a).r)\ CHECK_OVERFLOW_OP((res).i,+,(a).i)\ (res).r += (a).r; (res).i += (a).i;\ }while(0) #define C_SUBFROM( res , a)\ do {\ CHECK_OVERFLOW_OP((res).r,-,(a).r)\ CHECK_OVERFLOW_OP((res).i,-,(a).i)\ (res).r -= (a).r; (res).i -= (a).i; \ }while(0) #ifdef FIXED_POINT # define KISS_FFT_COS(phase) floor(.5+SAMP_MAX * cos (phase)) # define KISS_FFT_SIN(phase) floor(.5+SAMP_MAX * sin (phase)) # define HALF_OF(x) ((x)>>1) #elif defined(USE_SIMD) # define KISS_FFT_COS(phase) _mm_set1_ps( cos(phase) ) # define KISS_FFT_SIN(phase) _mm_set1_ps( sin(phase) ) # define HALF_OF(x) ((x)*_mm_set1_ps(.5)) #else # define KISS_FFT_COS(phase) (kiss_fft_scalar) cos(phase) # define KISS_FFT_SIN(phase) (kiss_fft_scalar) sin(phase) # define HALF_OF(x) ((x)*.5) #endif #define kf_cexp(x,phase) \ do{ \ (x)->r = KISS_FFT_COS(phase);\ (x)->i = KISS_FFT_SIN(phase);\ }while(0) /* a debugging function */ #define pcpx(c)\ fprintf(stderr,"%g + %gi\n",(double)((c)->r),(double)((c)->i) ) #ifdef KISS_FFT_USE_ALLOCA // define this to allow use of alloca instead of malloc for temporary buffers // Temporary buffers are used in two case: // 1. FFT sizes that have "bad" factors. i.e. not 2,3 and 5 // 2. "in-place" FFTs. Notice the quotes, since kissfft does not really do an in-place transform. #include #define KISS_FFT_TMP_ALLOC(nbytes) alloca(nbytes) #define KISS_FFT_TMP_FREE(ptr) #else #define KISS_FFT_TMP_ALLOC(nbytes) KISS_FFT_MALLOC(nbytes) #define KISS_FFT_TMP_FREE(ptr) KISS_FFT_FREE(ptr) #endif edfbrowser_153_source/third_party/kiss_fft/PaxHeaders.2978/kiss_fft.c0000644000175000001440000000013212251654530024264 xustar000000000000000030 mtime=1386699096.463032596 30 atime=1386699096.463032596 30 ctime=1386699096.463032596 edfbrowser_153_source/third_party/kiss_fft/kiss_fft.c0000644000175000001440000003056412251654530024025 0ustar00novarausers00000000000000/* Copyright (c) 2003-2010, Mark Borgerding All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "_kiss_fft_guts.h" /* The guts header contains all the multiplication and addition macros that are defined for fixed or floating point complex numbers. It also delares the kf_ internal functions. */ static void kf_bfly2( kiss_fft_cpx * Fout, const size_t fstride, const kiss_fft_cfg st, int m ) { kiss_fft_cpx * Fout2; kiss_fft_cpx * tw1 = st->twiddles; kiss_fft_cpx t; Fout2 = Fout + m; do{ C_FIXDIV(*Fout,2); C_FIXDIV(*Fout2,2); C_MUL (t, *Fout2 , *tw1); tw1 += fstride; C_SUB( *Fout2 , *Fout , t ); C_ADDTO( *Fout , t ); ++Fout2; ++Fout; }while (--m); } static void kf_bfly4( kiss_fft_cpx * Fout, const size_t fstride, const kiss_fft_cfg st, const size_t m ) { kiss_fft_cpx *tw1,*tw2,*tw3; kiss_fft_cpx scratch[6]; size_t k=m; const size_t m2=2*m; const size_t m3=3*m; tw3 = tw2 = tw1 = st->twiddles; do { C_FIXDIV(*Fout,4); C_FIXDIV(Fout[m],4); C_FIXDIV(Fout[m2],4); C_FIXDIV(Fout[m3],4); C_MUL(scratch[0],Fout[m] , *tw1 ); C_MUL(scratch[1],Fout[m2] , *tw2 ); C_MUL(scratch[2],Fout[m3] , *tw3 ); C_SUB( scratch[5] , *Fout, scratch[1] ); C_ADDTO(*Fout, scratch[1]); C_ADD( scratch[3] , scratch[0] , scratch[2] ); C_SUB( scratch[4] , scratch[0] , scratch[2] ); C_SUB( Fout[m2], *Fout, scratch[3] ); tw1 += fstride; tw2 += fstride*2; tw3 += fstride*3; C_ADDTO( *Fout , scratch[3] ); if(st->inverse) { Fout[m].r = scratch[5].r - scratch[4].i; Fout[m].i = scratch[5].i + scratch[4].r; Fout[m3].r = scratch[5].r + scratch[4].i; Fout[m3].i = scratch[5].i - scratch[4].r; }else{ Fout[m].r = scratch[5].r + scratch[4].i; Fout[m].i = scratch[5].i - scratch[4].r; Fout[m3].r = scratch[5].r - scratch[4].i; Fout[m3].i = scratch[5].i + scratch[4].r; } ++Fout; }while(--k); } static void kf_bfly3( kiss_fft_cpx * Fout, const size_t fstride, const kiss_fft_cfg st, size_t m ) { size_t k=m; const size_t m2 = 2*m; kiss_fft_cpx *tw1,*tw2; kiss_fft_cpx scratch[5]; kiss_fft_cpx epi3; epi3 = st->twiddles[fstride*m]; tw1=tw2=st->twiddles; do{ C_FIXDIV(*Fout,3); C_FIXDIV(Fout[m],3); C_FIXDIV(Fout[m2],3); C_MUL(scratch[1],Fout[m] , *tw1); C_MUL(scratch[2],Fout[m2] , *tw2); C_ADD(scratch[3],scratch[1],scratch[2]); C_SUB(scratch[0],scratch[1],scratch[2]); tw1 += fstride; tw2 += fstride*2; Fout[m].r = Fout->r - HALF_OF(scratch[3].r); Fout[m].i = Fout->i - HALF_OF(scratch[3].i); C_MULBYSCALAR( scratch[0] , epi3.i ); C_ADDTO(*Fout,scratch[3]); Fout[m2].r = Fout[m].r + scratch[0].i; Fout[m2].i = Fout[m].i - scratch[0].r; Fout[m].r -= scratch[0].i; Fout[m].i += scratch[0].r; ++Fout; }while(--k); } static void kf_bfly5( kiss_fft_cpx * Fout, const size_t fstride, const kiss_fft_cfg st, int m ) { kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4; int u; kiss_fft_cpx scratch[13]; kiss_fft_cpx * twiddles = st->twiddles; kiss_fft_cpx *tw; kiss_fft_cpx ya,yb; ya = twiddles[fstride*m]; yb = twiddles[fstride*2*m]; Fout0=Fout; Fout1=Fout0+m; Fout2=Fout0+2*m; Fout3=Fout0+3*m; Fout4=Fout0+4*m; tw=st->twiddles; for ( u=0; ur += scratch[7].r + scratch[8].r; Fout0->i += scratch[7].i + scratch[8].i; scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch[8].r,yb.r); scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch[8].i,yb.r); scratch[6].r = S_MUL(scratch[10].i,ya.i) + S_MUL(scratch[9].i,yb.i); scratch[6].i = -S_MUL(scratch[10].r,ya.i) - S_MUL(scratch[9].r,yb.i); C_SUB(*Fout1,scratch[5],scratch[6]); C_ADD(*Fout4,scratch[5],scratch[6]); scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r); scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r); scratch[12].r = - S_MUL(scratch[10].i,yb.i) + S_MUL(scratch[9].i,ya.i); scratch[12].i = S_MUL(scratch[10].r,yb.i) - S_MUL(scratch[9].r,ya.i); C_ADD(*Fout2,scratch[11],scratch[12]); C_SUB(*Fout3,scratch[11],scratch[12]); ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4; } } /* perform the butterfly for one stage of a mixed radix FFT */ static void kf_bfly_generic( kiss_fft_cpx * Fout, const size_t fstride, const kiss_fft_cfg st, int m, int p ) { int u,k,q1,q; kiss_fft_cpx * twiddles = st->twiddles; kiss_fft_cpx t; int Norig = st->nfft; kiss_fft_cpx * scratch = (kiss_fft_cpx*)KISS_FFT_TMP_ALLOC(sizeof(kiss_fft_cpx)*p); for ( u=0; u=Norig) twidx-=Norig; C_MUL(t,scratch[q] , twiddles[twidx] ); C_ADDTO( Fout[ k ] ,t); } k += m; } } KISS_FFT_TMP_FREE(scratch); } static void kf_work( kiss_fft_cpx * Fout, const kiss_fft_cpx * f, const size_t fstride, int in_stride, int * factors, const kiss_fft_cfg st ) { kiss_fft_cpx * Fout_beg=Fout; const int p=*factors++; /* the radix */ const int m=*factors++; /* stage's fft length/p */ const kiss_fft_cpx * Fout_end = Fout + p*m; #ifdef _OPENMP // use openmp extensions at the // top-level (not recursive) if (fstride==1 && p<=5) { int k; // execute the p different work units in different threads # pragma omp parallel for for (k=0;k floor_sqrt) p = n; /* no more factors, skip to end */ } n /= p; *facbuf++ = p; *facbuf++ = n; } while (n > 1); } /* * * User-callable function to allocate all necessary storage space for the fft. * * The return value is a contiguous block of memory, allocated with malloc. As such, * It can be freed with free(), rather than a kiss_fft-specific function. * */ kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem ) { kiss_fft_cfg st=NULL; size_t memneeded = sizeof(struct kiss_fft_state) + sizeof(kiss_fft_cpx)*(nfft-1); /* twiddle factors*/ if ( lenmem==NULL ) { st = ( kiss_fft_cfg)KISS_FFT_MALLOC( memneeded ); }else{ if (mem != NULL && *lenmem >= memneeded) st = (kiss_fft_cfg)mem; *lenmem = memneeded; } if (st) { int i; st->nfft=nfft; st->inverse = inverse_fft; for (i=0;iinverse) phase *= -1; kf_cexp(st->twiddles+i, phase ); } kf_factor(nfft,st->factors); } return st; } void kiss_fft_stride(kiss_fft_cfg st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int in_stride) { if (fin == fout) { //NOTE: this is not really an in-place FFT algorithm. //It just performs an out-of-place FFT into a temp buffer kiss_fft_cpx * tmpbuf = (kiss_fft_cpx*)KISS_FFT_TMP_ALLOC( sizeof(kiss_fft_cpx)*st->nfft); kf_work(tmpbuf,fin,1,in_stride, st->factors,st); memcpy(fout,tmpbuf,sizeof(kiss_fft_cpx)*st->nfft); KISS_FFT_TMP_FREE(tmpbuf); }else{ kf_work( fout, fin, 1,in_stride, st->factors,st ); } } void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout) { kiss_fft_stride(cfg,fin,fout,1); } void kiss_fft_cleanup(void) { // nothing needed any more } int kiss_fft_next_fast_size(int n) { while(1) { int m=n; while ( (m%2) == 0 ) m/=2; while ( (m%3) == 0 ) m/=3; while ( (m%5) == 0 ) m/=5; if (m<=1) break; /* n is completely factorable by twos, threes, and fives */ n++; } return n; } edfbrowser_153_source/third_party/kiss_fft/PaxHeaders.2978/kiss_fftr.c0000644000175000001440000000013212251654530024446 xustar000000000000000030 mtime=1386699096.463032596 30 atime=1386699096.463032596 30 ctime=1386699096.463032596 edfbrowser_153_source/third_party/kiss_fft/kiss_fftr.c0000644000175000001440000001347312251654530024207 0ustar00novarausers00000000000000/* Copyright (c) 2003-2004, Mark Borgerding All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "kiss_fftr.h" #include "_kiss_fft_guts.h" struct kiss_fftr_state{ kiss_fft_cfg substate; kiss_fft_cpx * tmpbuf; kiss_fft_cpx * super_twiddles; #ifdef USE_SIMD void * pad; #endif }; kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem) { int i; kiss_fftr_cfg st = NULL; size_t subsize, memneeded; if (nfft & 1) { fprintf(stderr,"Real FFT optimization must be even.\n"); return NULL; } nfft >>= 1; kiss_fft_alloc (nfft, inverse_fft, NULL, &subsize); memneeded = sizeof(struct kiss_fftr_state) + subsize + sizeof(kiss_fft_cpx) * ( nfft * 3 / 2); if (lenmem == NULL) { st = (kiss_fftr_cfg) KISS_FFT_MALLOC (memneeded); } else { if (*lenmem >= memneeded) st = (kiss_fftr_cfg) mem; *lenmem = memneeded; } if (!st) return NULL; st->substate = (kiss_fft_cfg) (st + 1); /*just beyond kiss_fftr_state struct */ st->tmpbuf = (kiss_fft_cpx *) (((char *) st->substate) + subsize); st->super_twiddles = st->tmpbuf + nfft; kiss_fft_alloc(nfft, inverse_fft, st->substate, &subsize); for (i = 0; i < nfft/2; ++i) { double phase = -3.14159265358979323846264338327 * ((double) (i+1) / nfft + .5); if (inverse_fft) phase *= -1; kf_cexp (st->super_twiddles+i,phase); } return st; } void kiss_fftr(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata) { /* input buffer timedata is stored row-wise */ int k,ncfft; kiss_fft_cpx fpnk,fpk,f1k,f2k,tw,tdc; if ( st->substate->inverse) { fprintf(stderr,"kiss fft usage error: improper alloc\n"); exit(1); } ncfft = st->substate->nfft; /*perform the parallel fft of two real signals packed in real,imag*/ kiss_fft( st->substate , (const kiss_fft_cpx*)timedata, st->tmpbuf ); /* The real part of the DC element of the frequency spectrum in st->tmpbuf * contains the sum of the even-numbered elements of the input time sequence * The imag part is the sum of the odd-numbered elements * * The sum of tdc.r and tdc.i is the sum of the input time sequence. * yielding DC of input time sequence * The difference of tdc.r - tdc.i is the sum of the input (dot product) [1,-1,1,-1... * yielding Nyquist bin of input time sequence */ tdc.r = st->tmpbuf[0].r; tdc.i = st->tmpbuf[0].i; C_FIXDIV(tdc,2); CHECK_OVERFLOW_OP(tdc.r ,+, tdc.i); CHECK_OVERFLOW_OP(tdc.r ,-, tdc.i); freqdata[0].r = tdc.r + tdc.i; freqdata[ncfft].r = tdc.r - tdc.i; #ifdef USE_SIMD freqdata[ncfft].i = freqdata[0].i = _mm_set1_ps(0); #else freqdata[ncfft].i = freqdata[0].i = 0; #endif for ( k=1;k <= ncfft/2 ; ++k ) { fpk = st->tmpbuf[k]; fpnk.r = st->tmpbuf[ncfft-k].r; fpnk.i = - st->tmpbuf[ncfft-k].i; C_FIXDIV(fpk,2); C_FIXDIV(fpnk,2); C_ADD( f1k, fpk , fpnk ); C_SUB( f2k, fpk , fpnk ); C_MUL( tw , f2k , st->super_twiddles[k-1]); freqdata[k].r = HALF_OF(f1k.r + tw.r); freqdata[k].i = HALF_OF(f1k.i + tw.i); freqdata[ncfft-k].r = HALF_OF(f1k.r - tw.r); freqdata[ncfft-k].i = HALF_OF(tw.i - f1k.i); } } void kiss_fftri(kiss_fftr_cfg st,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata) { /* input buffer timedata is stored row-wise */ int k, ncfft; if (st->substate->inverse == 0) { fprintf (stderr, "kiss fft usage error: improper alloc\n"); exit (1); } ncfft = st->substate->nfft; st->tmpbuf[0].r = freqdata[0].r + freqdata[ncfft].r; st->tmpbuf[0].i = freqdata[0].r - freqdata[ncfft].r; C_FIXDIV(st->tmpbuf[0],2); for (k = 1; k <= ncfft / 2; ++k) { kiss_fft_cpx fk, fnkc, fek, fok, tmp; fk = freqdata[k]; fnkc.r = freqdata[ncfft - k].r; fnkc.i = -freqdata[ncfft - k].i; C_FIXDIV( fk , 2 ); C_FIXDIV( fnkc , 2 ); C_ADD (fek, fk, fnkc); C_SUB (tmp, fk, fnkc); C_MUL (fok, tmp, st->super_twiddles[k-1]); C_ADD (st->tmpbuf[k], fek, fok); C_SUB (st->tmpbuf[ncfft - k], fek, fok); #ifdef USE_SIMD st->tmpbuf[ncfft - k].i *= _mm_set1_ps(-1.0); #else st->tmpbuf[ncfft - k].i *= -1; #endif } kiss_fft (st->substate, st->tmpbuf, (kiss_fft_cpx *) timedata); } edfbrowser_153_source/third_party/PaxHeaders.2978/fidlib0000644000175000001440000000013212251654530021654 xustar000000000000000030 mtime=1386699096.463032596 30 atime=1386699096.463032596 30 ctime=1386699096.463032596 edfbrowser_153_source/third_party/fidlib/0000755000175000001440000000000012251654530021462 5ustar00novarausers00000000000000edfbrowser_153_source/third_party/fidlib/PaxHeaders.2978/fidmkf.h0000644000175000001440000000013212251654530023342 xustar000000000000000030 mtime=1386699096.463032596 30 atime=1386699096.463032596 30 ctime=1386699096.463032596 edfbrowser_153_source/third_party/fidlib/fidmkf.h0000644000175000001440000005214112251654530023076 0ustar00novarausers00000000000000// // mkfilter-derived code // --------------------- // // Copyright (c) 2002-2004 Jim Peters . This // file is released under the GNU Lesser General Public License // (LGPL) version 2.1 as published by the Free Software // Foundation. See the file COPYING_LIB for details, or visit // . // // This is all code derived from 'mkfilter' by Tony Fisher of the // University of York. I've rewritten it all in C, and given it // a thorough overhaul, so there is actually none of his code // here any more, but it is all still very strongly based on the // algorithms and techniques that he used in 'mkfilter'. // // For those who didn't hear, Tony Fisher died in February 2000 // at the age of 43. See his web-site for information and a // tribute: // // http://www-users.cs.york.ac.uk/~fisher/ // http://www-users.cs.york.ac.uk/~fisher/tribute.html // // The original C++ sources and the rest of the mkfilter tool-set // are still available from his site: // // http://www-users.cs.york.ac.uk/~fisher/mkfilter/ // // // I've made a number of improvements and changes whilst // rewriting the code in C. For example, I halved the // calculations required in designing the filters by storing only // one complex pole/zero out of each conjugate pair. This also // made it much easier to output the filter as a list of // sub-filters without lots of searching around to match up // conjugate pairs later on. Outputting as a list of subfilters // permits greater accuracy in calculation of the response, and // also in the execution of the final filter. Also, some FIR // coefficients can be marked as 'constant', allowing optimised // routines to be generated for whole classes of filters, with // just the variable coefficients filled in at run-time. // // On the down-side, complex numbers are not portably available // in C before C99, so complex calculations here are done on // double[] arrays with inline functions, which ends up looking // more like assembly language than C. Never mind. // // // LEGAL STUFF // ----------- // // Tony Fisher released his software on his University of York // pages for free use and free download. The software itself has // no licence terms attached, nor copyright messages, just the // author's name, E-mail address and date. Nor are there any // licence terms indicated on the website. I understand that // under the Berne convention copyright does not have to be // claimed explicitly, so these are in fact copyright files by // legal default. However, the intention was obviously that // these files should be used by others. // // None of this really helps, though, if we're going to try to be // 100% legally correct, so I wrote to Anthony Moulds who is the // contact name on Tony Fisher's pages now. I explained what I // planned to do with the code, and he answered as follows: // // (Note that I was planning to use it 'as-is' at that time, // rather than rewrite it as I have done now) // // > To: "Jim Peters" // > From: "Anthony Moulds" // > Subject: RE: mkfilter source // > Date: Tue, 29 Oct 2002 15:30:19 -0000 // > // > Hi Jim, // > // > Thanks for your email. // > // > The University will be happy to let you use Dr Fisher's mkfilter // > code since your intention is not to profit financially from his work. // > // > It would be nice if in some way you could acknowledge his contribution. // > // > Best wishes and good luck with your work, // > // > Anthony Moulds // > Senior Experimental Officer, // > Computer Science Department, University of York, // > York, England, UK. Tel: 44(0)1904 434758 Fax: 44(0)19042767 // > ============================================================ // > // > // > > -----Original Message----- // > > From: Jim Peters [mailto:jim@uazu.net] // > > Sent: Monday, October 28, 2002 12:36 PM // > > To: anthony@cs.york.ac.uk // > > Subject: mkfilter source // > > // > > // > > I'm very sorry to hear (rather late, I know) that Tony Fisher died -- // > > I've always gone straight to the filter page, rather than through his // > > home page. I hope his work remains available for the future. // > > // > > Anyway, the reason I'm writing is to clarify the status of the // > > mkfilter source code. Because copyright is not claimed on the web // > > page nor in the source distribution, I guess that Tony's intention was // > > that this code should be in the public domain. However, I would like // > > to check this now to avoid complications later. // > > // > > I am using his code, modified, to provide a library of filter-design // > > routines for a GPL'd filter design app, which is not yet released. // > > The library could also be used standalone, permitting apps to design // > > filters at run-time rather than using hard-coded compile-time filters. // > > My interest in filters is as a part of my work on the OpenEEG project // // So this looks pretty clear to me. I am not planning to profit // from the work, so everything is fine with the University. I // guess others might profit from the work, indirectly, as with // any free software release, but so long as I don't, we're fine. // // I hope this is watertight enough for Debian/etc. Otherwise // I'll have to go back to Anthony Moulds for clarification. // // Even though there is no code cut-and-pasted from 'mkfilter' // here, it is all very obviously based on that code, so it // probably counts as a derived work -- although as ever "I Am // Not A Lawyer". // #ifdef HUGE_VAL #define INF HUGE_VAL #else #define INF (1.0/0.0) #endif #define TWOPI (2*M_PI) // // Complex square root: aa= aa^0.5 // STATIC_INLINE double my_sqrt(double aa) { return aa <= 0.0 ? 0.0 : sqrt(aa); } // 'csqrt' clashes with builtin in GCC 4, so call it 'c_sqrt' STATIC_INLINE void c_sqrt(double *aa) { double mag= hypot(aa[0], aa[1]); double rr= my_sqrt((mag + aa[0]) * 0.5); double ii= my_sqrt((mag - aa[0]) * 0.5); if (aa[1] < 0.0) ii= -ii; aa[0]= rr; aa[1]= ii; } // // Complex imaginary exponent: aa= e^i.theta // STATIC_INLINE void cexpj(double *aa, double theta) { aa[0]= cos(theta); aa[1]= sin(theta); } // // Complex exponent: aa= e^aa // // 'cexp' clashes with builtin in GCC 4, so call it 'c_exp' STATIC_INLINE void c_exp(double *aa) { double mag= exp(aa[0]); aa[0]= mag * cos(aa[1]); aa[1]= mag * sin(aa[1]); } // // Global temp buffer for generating filters. *NOT THREAD SAFE* // // Note that the poles and zeros are stored in a strange way. // Rather than storing both a pole (or zero) and its complex // conjugate, I'm storing just one of the pair. Also, for real // poles, I'm not storing the imaginary part (which is zero). // This results in a list of numbers exactly half the length you // might otherwise expect. However, since some of these numbers // are in pairs, and some are single, we need a separate flag // array to indicate which is which. poltyp[] serves this // purpose. An entry is 1 if the corresponding offset is a real // pole, or 2 if it is the first of a pair of values making up a // complex pole. The second value of the pair has an entry of 0 // attached. (Similarly for zeros in zertyp[]) // #define MAXPZ 64 static int n_pol; // Number of poles static double pol[MAXPZ]; // Pole values (see above) static char poltyp[MAXPZ]; // Pole value types: 1 real, 2 first of complex pair, 0 second static int n_zer; // Same for zeros ... static double zer[MAXPZ]; static char zertyp[MAXPZ]; // // Pre-warp a frequency // STATIC_INLINE double prewarp(double val) { return tan(val * M_PI) / M_PI; } // // Bessel poles; final one is a real value for odd numbers of // poles // static double bessel_1[]= { -1.00000000000e+00 }; static double bessel_2[]= { -1.10160133059e+00, 6.36009824757e-01, }; static double bessel_3[]= { -1.04740916101e+00, 9.99264436281e-01, -1.32267579991e+00, }; static double bessel_4[]= { -9.95208764350e-01, 1.25710573945e+00, -1.37006783055e+00, 4.10249717494e-01, }; static double bessel_5[]= { -9.57676548563e-01, 1.47112432073e+00, -1.38087732586e+00, 7.17909587627e-01, -1.50231627145e+00, }; static double bessel_6[]= { -9.30656522947e-01, 1.66186326894e+00, -1.38185809760e+00, 9.71471890712e-01, -1.57149040362e+00, 3.20896374221e-01, }; static double bessel_7[]= { -9.09867780623e-01, 1.83645135304e+00, -1.37890321680e+00, 1.19156677780e+00, -1.61203876622e+00, 5.89244506931e-01, -1.68436817927e+00, }; static double bessel_8[]= { -8.92869718847e-01, 1.99832584364e+00, -1.37384121764e+00, 1.38835657588e+00, -1.63693941813e+00, 8.22795625139e-01, -1.75740840040e+00, 2.72867575103e-01, }; static double bessel_9[]= { -8.78399276161e-01, 2.14980052431e+00, -1.36758830979e+00, 1.56773371224e+00, -1.65239648458e+00, 1.03138956698e+00, -1.80717053496e+00, 5.12383730575e-01, -1.85660050123e+00, }; static double bessel_10[]= { -8.65756901707e-01, 2.29260483098e+00, -1.36069227838e+00, 1.73350574267e+00, -1.66181024140e+00, 1.22110021857e+00, -1.84219624443e+00, 7.27257597722e-01, -1.92761969145e+00, 2.41623471082e-01, }; static double *bessel_poles[10]= { bessel_1, bessel_2, bessel_3, bessel_4, bessel_5, bessel_6, bessel_7, bessel_8, bessel_9, bessel_10 }; // // Generate Bessel poles for the given order. // static void bessel(int order) { int a; if (order > 10) error("Maximum Bessel order is 10"); n_pol= order; memcpy(pol, bessel_poles[order-1], n_pol * sizeof(double)); for (a= 0; a MAXPZ) error("Maximum butterworth/chebyshev order is %d", MAXPZ); n_pol= order; for (a= 0; a= 0.0) error("Chebyshev ripple in dB should be -ve"); eps= sqrt(-1.0 + pow(10.0, -0.1 * ripple)); y= asinh(1.0 / eps) / order; if (y <= 0.0) error("Internal error; chebyshev y-value <= 0.0: %g", y); sh= sinh(y); ch= cosh(y); for (a= 0; a MAXPZ) error("Maximum order for bandpass filters is %d", MAXPZ/2); // Run through the list backwards, expanding as we go for (a= n_pol, b= n_pol*2; a>0; ) { // hba= pole * bw; // temp= c_sqrt(1.0 - square(w0 / hba)); // pole1= hba * (1.0 + temp); // pole2= hba * (1.0 - temp); if (poltyp[a-1] == 1) { double hba; a--; b -= 2; poltyp[b]= 2; poltyp[b+1]= 0; hba= pol[a] * bw; cassz(pol+b, 1.0 - (w0 / hba) * (w0 / hba), 0.0); c_sqrt(pol+b); caddz(pol+b, 1.0, 0.0); cmulr(pol+b, hba); } else { // Assume poltyp[] data is valid double hba[2]; a -= 2; b -= 4; poltyp[b]= 2; poltyp[b+1]= 0; poltyp[b+2]= 2; poltyp[b+3]= 0; cass(hba, pol+a); cmulr(hba, bw); cass(pol+b, hba); crecip(pol+b); cmulr(pol+b, w0); csqu(pol+b); cneg(pol+b); caddz(pol+b, 1.0, 0.0); c_sqrt(pol+b); cmul(pol+b, hba); cass(pol+b+2, pol+b); cneg(pol+b+2); cadd(pol+b, hba); cadd(pol+b+2, hba); } } n_pol *= 2; // Add zeros n_zer= n_pol; for (a= 0; a MAXPZ) error("Maximum order for bandstop filters is %d", MAXPZ/2); // Run through the list backwards, expanding as we go for (a= n_pol, b= n_pol*2; a>0; ) { // hba= bw / pole; // temp= c_sqrt(1.0 - square(w0 / hba)); // pole1= hba * (1.0 + temp); // pole2= hba * (1.0 - temp); if (poltyp[a-1] == 1) { double hba; a--; b -= 2; poltyp[b]= 2; poltyp[b+1]= 0; hba= bw / pol[a]; cassz(pol+b, 1.0 - (w0 / hba) * (w0 / hba), 0.0); c_sqrt(pol+b); caddz(pol+b, 1.0, 0.0); cmulr(pol+b, hba); } else { // Assume poltyp[] data is valid double hba[2]; a -= 2; b -= 4; poltyp[b]= 2; poltyp[b+1]= 0; poltyp[b+2]= 2; poltyp[b+3]= 0; cass(hba, pol+a); crecip(hba); cmulr(hba, bw); cass(pol+b, hba); crecip(pol+b); cmulr(pol+b, w0); csqu(pol+b); cneg(pol+b); caddz(pol+b, 1.0, 0.0); c_sqrt(pol+b); cmul(pol+b, hba); cass(pol+b+2, pol+b); cneg(pol+b+2); cadd(pol+b, hba); cadd(pol+b+2, hba); } } n_pol *= 2; // Add zeros n_zer= n_pol; for (a= 0; atyp= 'F'; ff->len= 1; ff->val[0]= gain; ff= FFNEXT(ff); // Output as much as possible as 2x2 IIR/FIR filters for (a= 0; a <= n_pol-2 && a <= n_zer-2; a += 2) { // Look for a pair of values for an IIR if (poltyp[a] == 1 && poltyp[a+1] == 1) { // Two real values ff->typ= 'I'; ff->len= 3; ff->val[0]= 1; ff->val[1]= -(pol[a] + pol[a+1]); ff->val[2]= pol[a] * pol[a+1]; ff= FFNEXT(ff); } else if (poltyp[a] == 2) { // A complex value and its conjugate pair ff->typ= 'I'; ff->len= 3; ff->val[0]= 1; ff->val[1]= -2 * pol[a]; ff->val[2]= pol[a] * pol[a] + pol[a+1] * pol[a+1]; ff= FFNEXT(ff); } else error("Internal error -- bad poltyp[] values for z2fidfilter()"); // Look for a pair of values for an FIR if (zertyp[a] == 1 && zertyp[a+1] == 1) { // Two real values // Skip if constant and 0/0 if (!cbm || zer[a] != 0.0 || zer[a+1] != 0.0) { ff->typ= 'F'; ff->cbm= cbm; ff->len= 3; ff->val[0]= 1; ff->val[1]= -(zer[a] + zer[a+1]); ff->val[2]= zer[a] * zer[a+1]; ff= FFNEXT(ff); } } else if (zertyp[a] == 2) { // A complex value and its conjugate pair // Skip if constant and 0/0 if (!cbm || zer[a] != 0.0 || zer[a+1] != 0.0) { ff->typ= 'F'; ff->cbm= cbm; ff->len= 3; ff->val[0]= 1; ff->val[1]= -2 * zer[a]; ff->val[2]= zer[a] * zer[a] + zer[a+1] * zer[a+1]; ff= FFNEXT(ff); } } else error("Internal error -- bad zertyp[] values"); } // Clear up any remaining bits and pieces. Should only be a 1x1 // IIR/FIR. if (n_pol-a == 0 && n_zer-a == 0) ; else if (n_pol-a == 1 && n_zer-a == 1) { if (poltyp[a] != 1 || zertyp[a] != 1) error("Internal error; bad poltyp or zertyp for final pole/zero"); ff->typ= 'I'; ff->len= 2; ff->val[0]= 1; ff->val[1]= -pol[a]; ff= FFNEXT(ff); // Skip FIR if it is constant and zero if (!cbm || zer[a] != 0.0) { ff->typ= 'F'; ff->cbm= cbm; ff->len= 2; ff->val[0]= 1; ff->val[1]= -zer[a]; ff= FFNEXT(ff); } } else error("Internal error: unexpected poles/zeros at end of list"); // End of list ff->typ= 0; ff->len= 0; ff= FFNEXT(ff); rv= realloc(rv, ((char*)ff)-((char*)rv)); if (!rv) error("Out of memory"); return rv; } // // Setup poles/zeros for a band-pass resonator. 'qfact' gives // the Q-factor; 0 is a special value indicating +infinity, // giving an oscillator. // static void bandpass_res(double freq, double qfact) { double mag; double th0, th1, th2; double theta= freq * TWOPI; double val[2]; double tmp1[2], tmp2[2], tmp3[2], tmp4[2]; int cnt; n_pol= 2; poltyp[0]= 2; poltyp[1]= 0; n_zer= 2; zertyp[0]= 1; zertyp[1]= 1; zer[0]= 1; zer[1]= -1; if (qfact == 0.0) { cexpj(pol, theta); return; } // Do a full binary search, rather than seeding it as Tony Fisher does cexpj(val, theta); mag= exp(-theta / (2.0 * qfact)); th0= 0; th2= M_PI; for (cnt= 60; cnt > 0; cnt--) { th1= 0.5 * (th0 + th2); cexpj(pol, th1); cmulr(pol, mag); // Evaluate response of filter for Z= val memcpy(tmp1, val, 2*sizeof(double)); memcpy(tmp2, val, 2*sizeof(double)); memcpy(tmp3, val, 2*sizeof(double)); memcpy(tmp4, val, 2*sizeof(double)); csubz(tmp1, 1, 0); csubz(tmp2, -1, 0); cmul(tmp1, tmp2); csub(tmp3, pol); cconj(pol); csub(tmp4, pol); cconj(pol); cmul(tmp3, tmp4); cdiv(tmp1, tmp3); if (fabs(tmp1[1] / tmp1[0]) < 1e-10) break; //printf("%-24.16g%-24.16g -> %-24.16g%-24.16g\n", th0, th2, tmp1[0], tmp1[1]); if (tmp1[1] > 0.0) th2= th1; else th0= th1; } if (cnt <= 0) fprintf(stderr, "Resonator binary search failed to converge"); } // // Setup poles/zeros for a bandstop resonator // static void bandstop_res(double freq, double qfact) { bandpass_res(freq, qfact); zertyp[0]= 2; zertyp[1]= 0; cexpj(zer, TWOPI * freq); } // // Setup poles/zeros for an allpass resonator // static void allpass_res(double freq, double qfact) { bandpass_res(freq, qfact); zertyp[0]= 2; zertyp[1]= 0; memcpy(zer, pol, 2*sizeof(double)); cmulr(zer, 1.0 / (zer[0]*zer[0] + zer[1]*zer[1])); } // // Setup poles/zeros for a proportional-integral filter // static void prop_integral(double freq) { n_pol= 1; poltyp[0]= 1; pol[0]= 0.0; n_zer= 1; zertyp[0]= 1; zer[0]= -TWOPI * freq; } // END // edfbrowser_153_source/third_party/fidlib/PaxHeaders.2978/fidlib.h0000644000175000001440000000013212251654530023333 xustar000000000000000030 mtime=1386699096.463032596 30 atime=1386699096.463032596 30 ctime=1386699096.463032596 edfbrowser_153_source/third_party/fidlib/fidlib.h0000644000175000001440000000545412251654530023074 0ustar00novarausers00000000000000// // fidlib include file // #ifndef FIDLIB_INCLUDED #define FIDLIB_INCLUDED typedef struct FidFilter FidFilter; struct FidFilter { short typ; // Type of filter element 'I' IIR, 'F' FIR, or 0 for end of list short cbm; // Constant bitmap. Bits 0..14, if set, indicate that val[0..14] // is a constant across changes in frequency for this filter type // Bit 15, if set, indicates that val[15..inf] are constant. int len; // Number of doubles stored in val[], or 0 for end of list double val[1]; }; // Lets you write: for (; ff->typ; ff= FFNEXT(ff)) { ... } #define FFNEXT(ff) ((FidFilter*)((ff)->val + (ff)->len)) // Size of a sub-filter with 'cnt' double values attached #define FFSIZE(cnt) (sizeof(FidFilter) + ((cnt)-1)*sizeof(double)) // Size required for the memory chunk to contain the given number // headers and values, plus termination #define FFCSIZE(n_head,n_val) ((sizeof(FidFilter)-sizeof(double))*((n_head)+1) + sizeof(double)*(n_val)) // Allocate the chunk of memory to hold a list of FidFilters, with // n_head FidFilters and n_val total double values in the whole list. // Includes space for the final termination, and zeros the memory. #define FFALLOC(n_head,n_val) (FidFilter*)Alloc(FFCSIZE(n_head, n_val)) // These are so you can use easier names to refer to running filters typedef void FidRun; typedef double (FidFunc)(void*, double); // // Prototypes // #ifdef __cplusplus extern "C" { #endif extern void fid_set_error_handler(void(*rout)(char *)); extern char *fid_version(); extern double fid_response_pha(FidFilter *filt, double freq, double *phase); extern double fid_response(FidFilter *filt, double freq); extern int fid_calc_delay(FidFilter *filt); extern FidFilter *fid_design(char *spec, double rate, double freq0, double freq1, int f_adj, char **descp); extern double fid_design_coef(double *coef, int n_coef, char *spec, double rate, double freq0, double freq1, int adj); extern void fid_list_filters(FILE *out); extern int fid_list_filters_buf(char *buf, char *bufend); extern FidFilter *fid_flatten(FidFilter *filt); extern void fid_rewrite_spec(char *spec, double freq0, double freq1, int adj, char **spec1p, char **spec2p, double *freq0p, double *freq1p, int *adjp); extern FidFilter *fid_cv_array(double *arr); extern FidFilter *fid_cat(int freeme, ...); extern char *fid_parse(double rate, char **pp, FidFilter **ffp); // // Filter running prototypes // extern void *fid_run_new(FidFilter *filt, double(**funcpp)(void *, double)); extern void *fid_run_newbuf(void *run); extern int fid_run_bufsize(void *run); extern void fid_run_initbuf(void *run, void *buf); extern void fid_run_zapbuf(void *buf); extern void fid_run_freebuf(void *runbuf); extern void fid_run_free(void *run); #ifdef __cplusplus } /* extern "C" */ #endif #endif edfbrowser_153_source/third_party/fidlib/PaxHeaders.2978/fidlib.c0000644000175000001440000000013212251654530023326 xustar000000000000000030 mtime=1386699096.463032596 30 atime=1386699096.463032596 30 ctime=1386699096.463032596 edfbrowser_153_source/third_party/fidlib/fidlib.c0000644000175000001440000017224312251654530023070 0ustar00novarausers00000000000000// // Fidlib digital filter designer code // ----------------------------------- // // Copyright (c) 2002-2004 Jim Peters . This // file is released under the GNU Lesser General Public License // (LGPL) version 2.1 as published by the Free Software // Foundation. See the file COPYING_LIB for details, or visit // . // // The code in this file was written to go with the Fiview app // (http://uazu.net/fiview/), but it may be used as a library for // other applications. The idea behind this library is to allow // filters to be designed at run-time, which gives much greater // flexibility to filtering applications. // // This file depends on the fidmkf.h file which provides the // filter types from Tony Fisher's 'mkfilter' package. See that // file for references and links used there. // // // Here are some of the sources I used whilst writing this code: // // Robert Bristow-Johnson's EQ cookbook formulae: // http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt // #define VERSION "0.9.10" // // Filter specification string // --------------------------- // // The filter specification string can be used to completely // specify the filter, or it can be used with the frequency or // frequency range missing, in which case default values are // picked up from values passed directly to the routine. // // The spec consists of a series of letters usually followed by // the order of the filter and then by any other parameters // required, preceded by slashes. For example: // // LpBu4/20.4 Lowpass butterworth, 4th order, -3.01dB at 20.4Hz // BpBu2/3-4 Bandpass butterworth, 2nd order, from 3 to 4Hz // BpBu2/=3-4 Same filter, but adjusted exactly to the range given // BsRe/1000/10 Bandstop resonator, Q=1000, frequency 10Hz // // The routines fid_design() or fid_parse() are used to convert // this spec-string into filter coefficients and a description // (if required). // // // Typical usage: // ------------- // // FidFilter *filt, *filt2; // char *desc; // FidRun *run; // FidFunc *funcp; // void *fbuf1, *fbuf2; // int delay; // void my_error_func(char *err); // // // Design a filter, and optionally get its long description // filt= fid_design(spec, rate, freq0, freq1, adj, &desc); // // // List all the possible filter types // fid_list_filters(stdout); // okay= fid_list_filters_buf(buf, buf+sizeof(buf)); // // // Calculate the response of the filter at a given frequency // // (frequency is given as a proportion of the sampling rate, in // // the range 0 to 0.5). If phase is returned, then this is // // given in the range 0 to 1 (for 0 to 2*pi). // resp= fid_response(filt, freq); // resp= fid_response_pha(filt, freq, &phase); // // // Estimate the signal delay caused by a particular filter, in samples // delay= fid_calc_delay(filt); // // // Run a given filter (this will do JIT filter compilation if this is // // implemented for this processor / OS) // run= fid_run_new(filt, &funcp); // fbuf1= fid_run_newbuf(run); // fbuf2= fid_run_newbuf(run); // while (...) { // out_1= funcp(fbuf1, in_1); // out_2= funcp(fbuf2, in_2); // if (restart_required) fid_run_zapbuf(fbuf1); // ... // } // fid_run_freebuf(fbuf2); // fid_run_freebuf(fbuf1); // fid_run_free(run); // // // If you need to allocate your own buffers separately for some // // reason, then do it this way: // run= fid_run_new(filt, &funcp); // len= fid_run_bufsize(run); // fbuf1= Alloc(len); fid_run_initbuf(run, fbuf1); // fbuf2= Alloc(len); fid_run_initbuf(run, fbuf2); // while (...) { // out_1= funcp(fbuf1, in_1); // out_2= funcp(fbuf2, in_2); // if (restart_required) fid_run_zapbuf(fbuf1); // ... // } // free(fbuf2); // free(fbuf1); // fid_run_free(run); // // // Convert an arbitrary filter into a new filter which is a single // // IIR/FIR pair. This is done by convolving the coefficients. This // // flattened filter will give the same result, in theory. However, // // in practice this will be less accurate, especially in cases where // // the limits of the floating point format are being reached (e.g. // // subtracting numbers with small highly significant differences). // // The routine also ensures that the IIR first coefficient is 1.0. // filt2= fid_flatten(filt); // free(filt); // // // Parse an entire filter-spec string possibly containing several FIR, // // IIR and predefined filters and return it as a FidFilter at the given // // location. Stops at the first ,; or unmatched )]} character, or the end // // of the string. Returns a strdup'd error string on error, or else 0. // err= fid_parse(double rate, char **pp, FidFilter **ffp); // // // Set up your own fatal-error handler (default is to dump a message // // to STDERR and exit on fatal conditions) // fid_set_error_handler(&my_error_func); // // // Get the version number of the library as a string (e.g. "1.0.0") // txt= fid_version(); // // // Design a filter and reduce it to a list of all the non-const // // coefficients, which is returned in the given double[]. The number // // of coefficients expected must be provided (as a check). // #define N_COEF // double coef[N_COEF], gain; // gain= fid_design_coef(coef, N_COEF, spec, rate, freq0, freq1, adj); // // // Rewrite a filter spec in a full and/or separated-out form // char *full, *min; // double minf0, minf1; // int minadj; // fid_rewrite_spec(spec, freq0, freq1, adj, &full, &min, &minf0, &minf1, &minadj); // ... // free(full); free(min); // // // Create a FidFilter based on coefficients provided in the // // given double array. // static double array[]= { 'I', 3, 1.0, 0.55, 0.77, 'F', 3, 1, -2, 1, 0 }; // filt= fid_cv_array(array); // // // Join a number of filters into a single filter (and free them too, // // if the first argument is 1) // filt= fid_cat(0, filt1, filt2, filt3, filt4, 0); // // // // Format of returned filter // ------------------------- // // The filter returned is a single chunk of allocated memory in // which is stored a number of FidFilter instances. Each // instance has variable length according to the coefficients // contained in it. It is probably easier to think of this as a // stream of items in memory. Each sub-filter starts with its // type as a short -- either 'I' for IIR filters, or 'F' for FIR // filters. (Other types may be added later, e.g. AM modulation // elements, or whatever). This is followed by a short bitmap // which indicates which of the coefficients are constants, // aiding code-generation. Next comes the count of the following // coefficients, as an int. (These header fields normally takes 8 // bytes, the same as a double, but this might depend on the // platform). Then follow the coefficients, as doubles. The next // sub-filter follows on straight after that. The end of the list // is marked by 8 zero bytes, meaning typ==0, cbm==0 and len==0. // // The filter can be read with the aid of the FidFilter structure // (giving typ, cbm, len and val[] elements) and the FFNEXT() // macro: using ff= FFNEXT(ff) steps to the next FidFilter // structure along the chain. // // Note that within the sub-filters, coefficients are listed in // the order that they apply to data, from current-sample // backwards in time, i.e. most recent first (so an FIR val[] of // 0, 0, 1 represents a two-sample delay FIR filter). IIR // filters are *not* necessarily adjusted so that their first // coefficient is 1. // // Most filters have their gain pre-adjusted so that some // suitable part of the response is at gain==1.0. However, this // depends on the filter type. // // // Check that a target macro has been set. This macro selects // various fixes required on various platforms: // // T_LINUX Linux, or probably any UNIX-like platform with GCC // T_MINGW MinGW -- either building on Win32 or cross-compiling // T_MSVC Microsoft Visual C // // (On MSVC, add "T_MSVC" to the preprocessor definitions in the // project settings, or add /D "T_MSVC" to the compiler // command-line.) // #ifdef __MINGW32__ #define T_MINGW #else #define T_LINUX #endif #ifndef T_LINUX #ifndef T_MINGW #ifndef T_MSVC #error Please define one of the T_* target macros (e.g. -DT_LINUX); see fidlib.c #endif #endif #endif // // Select which method of filter execution is preferred. // RF_CMDLIST is recommended (and is the default). // // RF_COMBINED -- easy to understand code, lower accuracy // RF_CMDLIST -- faster pre-compiled code // RF_JIT -- fastest JIT run-time generated code (no longer supported) // #ifndef RF_COMBINED #ifndef RF_CMDLIST #ifndef RF_JIT #define RF_CMDLIST #endif #endif #endif // // Includes // #include #include #include #include #include #include #include "fidlib.h" #ifndef M_PI #define M_PI 3.14159265358979323846 #endif extern FidFilter *mkfilter(char *, ...); // // Target-specific fixes // // Macro for local inline routines that shouldn't be visible externally #ifdef T_MSVC #define STATIC_INLINE static __inline #else #define STATIC_INLINE static inline #endif // MinGW and MSVC fixes #if defined(T_MINGW) || defined(T_MSVC) #ifndef vsnprintf #define vsnprintf _vsnprintf #endif #ifndef snprintf #define snprintf _snprintf #endif // Not sure if we strictly need this still STATIC_INLINE double my_asinh(double val) { return log(val + sqrt(val*val + 1.0)); } #define asinh(xx) my_asinh(xx) #endif // // Support code // static void (*error_handler)(char *err)= 0; static void error(char *fmt, ...) { char buf[1024]; va_list ap; va_start(ap, fmt); vsnprintf(buf, sizeof(buf), fmt, ap); // Ignore overflow buf[sizeof(buf)-1]= 0; if (error_handler) error_handler(buf); // If error handler routine returns, we dump to STDERR and exit anyway fprintf(stderr, "fidlib error: %s\n", buf); exit(1); } static char * strdupf(char *fmt, ...) { va_list ap; char buf[1024], *rv; int len; va_start(ap, fmt); len= vsnprintf(buf, sizeof(buf), fmt, ap); if (len < 0 || len >= sizeof(buf)-1) error("strdupf exceeded buffer"); rv= strdup(buf); if (!rv) error("Out of memory"); return rv; } static void * Alloc(int size) { void *vp= calloc(1, size); if (!vp) error("Out of memory"); return vp; } #define ALLOC(type) ((type*)Alloc(sizeof(type))) #define ALLOC_ARR(cnt, type) ((type*)Alloc((cnt) * sizeof(type))) // // Complex multiply: aa *= bb; // STATIC_INLINE void cmul(double *aa, double *bb) { double rr= aa[0] * bb[0] - aa[1] * bb[1]; double ii= aa[0] * bb[1] + aa[1] * bb[0]; aa[0]= rr; aa[1]= ii; } // // Complex square: aa *= aa; // STATIC_INLINE void csqu(double *aa) { double rr= aa[0] * aa[0] - aa[1] * aa[1]; double ii= 2 * aa[0] * aa[1]; aa[0]= rr; aa[1]= ii; } // // Complex multiply by real: aa *= bb; // STATIC_INLINE void cmulr(double *aa, double fact) { aa[0] *= fact; aa[1] *= fact; } // // Complex conjugate: aa= aa* // STATIC_INLINE void cconj(double *aa) { aa[1]= -aa[1]; } // // Complex divide: aa /= bb; // STATIC_INLINE void cdiv(double *aa, double *bb) { double rr= aa[0] * bb[0] + aa[1] * bb[1]; double ii= -aa[0] * bb[1] + aa[1] * bb[0]; double fact= 1.0 / (bb[0] * bb[0] + bb[1] * bb[1]); aa[0]= rr * fact; aa[1]= ii * fact; } // // Complex reciprocal: aa= 1/aa // STATIC_INLINE void crecip(double *aa) { double fact= 1.0 / (aa[0] * aa[0] + aa[1] * aa[1]); aa[0] *= fact; aa[1] *= -fact; } // // Complex assign: aa= bb // STATIC_INLINE void cass(double *aa, double *bb) { memcpy(aa, bb, 2*sizeof(double)); // Assigning doubles is really slow } // // Complex assign: aa= (rr + ii*j) // STATIC_INLINE void cassz(double *aa, double rr, double ii) { aa[0]= rr; aa[1]= ii; } // // Complex add: aa += bb // STATIC_INLINE void cadd(double *aa, double *bb) { aa[0] += bb[0]; aa[1] += bb[1]; } // // Complex add: aa += (rr + ii*j) // STATIC_INLINE void caddz(double *aa, double rr, double ii) { aa[0] += rr; aa[1] += ii; } // // Complex subtract: aa -= bb // STATIC_INLINE void csub(double *aa, double *bb) { aa[0] -= bb[0]; aa[1] -= bb[1]; } // // Complex subtract: aa -= (rr + ii*j) // STATIC_INLINE void csubz(double *aa, double rr, double ii) { aa[0] -= rr; aa[1] -= ii; } // // Complex negate: aa= -aa // STATIC_INLINE void cneg(double *aa) { aa[0]= -aa[0]; aa[1]= -aa[1]; } // // Evaluate a complex polynomial given the coefficients. // rv[0]+i*rv[1] is the result, in[0]+i*in[1] is the input value. // Coefficients are real values. // STATIC_INLINE void evaluate(double *rv, double *coef, int n_coef, double *in) { double pz[2]; // Powers of Z // Handle first iteration by hand rv[0]= *coef++; rv[1]= 0; if (--n_coef > 0) { // Handle second iteration by hand pz[0]= in[0]; pz[1]= in[1]; rv[0] += *coef * pz[0]; rv[1] += *coef * pz[1]; coef++; n_coef--; // Loop for remainder while (n_coef > 0) { cmul(pz, in); rv[0] += *coef * pz[0]; rv[1] += *coef * pz[1]; coef++; n_coef--; } } } // // Housekeeping // void fid_set_error_handler(void (*rout)(char*)) { error_handler= rout; } char * fid_version() { return VERSION; } // // Get the response and phase of a filter at the given frequency // (expressed as a proportion of the sampling rate, 0->0.5). // Phase is returned as a number from 0 to 1, representing a // phase between 0 and two-pi. // double fid_response_pha(FidFilter *filt, double freq, double *phase) { double top[2], bot[2]; double theta= freq * 2 * M_PI; double zz[2]; top[0]= 1; top[1]= 0; bot[0]= 1; bot[1]= 0; zz[0]= cos(theta); zz[1]= sin(theta); while (filt->len) { double resp[2]; int cnt= filt->len; evaluate(resp, filt->val, cnt, zz); if (filt->typ == 'I') cmul(bot, resp); else if (filt->typ == 'F') cmul(top, resp); else error("Unknown filter type %d in fid_response_pha()", filt->typ); filt= FFNEXT(filt); } cdiv(top, bot); if (phase) { double pha= atan2(top[1], top[0]) / (2 * M_PI); if (pha < 0) pha += 1.0; *phase= pha; } return hypot(top[1], top[0]); } // // Get the response of a filter at the given frequency (expressed // as a proportion of the sampling rate, 0->0.5). // // Code duplicate, as I didn't want the overhead of a function // call to fid_response_pha. Almost every call in this routine // can be inlined. // double fid_response(FidFilter *filt, double freq) { double top[2], bot[2]; double theta= freq * 2 * M_PI; double zz[2]; top[0]= 1; top[1]= 0; bot[0]= 1; bot[1]= 0; zz[0]= cos(theta); zz[1]= sin(theta); while (filt->len) { double resp[2]; int cnt= filt->len; evaluate(resp, filt->val, cnt, zz); if (filt->typ == 'I') cmul(bot, resp); else if (filt->typ == 'F') cmul(top, resp); else error("Unknown filter type %d in fid_response()", filt->typ); filt= FFNEXT(filt); } cdiv(top, bot); return hypot(top[1], top[0]); } // // Estimate the delay that a filter causes to the signal by // looking for the point at which 50% of the filter calculations // are complete. This involves running test impulses through the // filter several times. The estimated delay in samples is // returned. // // Delays longer than 8,000,000 samples are not handled well, as // the code drops out at this point rather than get stuck in an // endless loop. // int fid_calc_delay(FidFilter *filt) { FidRun *run; FidFunc *dostep; void *f1, *f2; double tot, tot100, tot50; int cnt; run= fid_run_new(filt, &dostep); // Run through to find at least the 99.9% point of filter; the r2 // (tot100) filter runs at 4x the speed of the other one to act as // a reference point much further ahead in the impulse response. f1= fid_run_newbuf(run); f2= fid_run_newbuf(run); tot= fabs(dostep(f1, 1.0)); tot100= fabs(dostep(f2, 1.0)); tot100 += fabs(dostep(f2, 0.0)); tot100 += fabs(dostep(f2, 0.0)); tot100 += fabs(dostep(f2, 0.0)); for (cnt= 1; cnt < 0x1000000; cnt++) { tot += fabs(dostep(f1, 0.0)); tot100 += fabs(dostep(f2, 0.0)); tot100 += fabs(dostep(f2, 0.0)); tot100 += fabs(dostep(f2, 0.0)); tot100 += fabs(dostep(f2, 0.0)); if (tot/tot100 >= 0.999) break; } fid_run_freebuf(f1); fid_run_freebuf(f2); // Now find the 50% point tot50= tot100/2; f1= fid_run_newbuf(run); tot= fabs(dostep(f1, 1.0)); for (cnt= 0; tot < tot50; cnt++) tot += fabs(dostep(f1, 0.0)); fid_run_freebuf(f1); // Clean up, return fid_run_free(run); return cnt; } // // 'mkfilter'-derived code // #include "fidmkf.h" // // Stack a number of identical filters, generating the required // FidFilter* return value // static FidFilter* stack_filter(int order, int n_head, int n_val, ...) { FidFilter *rv= FFALLOC(n_head * order, n_val * order); FidFilter *p, *q; va_list ap; int a, b, len; if (order == 0) return rv; // Copy from ap va_start(ap, n_val); p= q= rv; for (a= 0; atyp= va_arg(ap, int); p->cbm= va_arg(ap, int); p->len= va_arg(ap, int); for (b= 0; blen; b++) p->val[b]= va_arg(ap, double); p= FFNEXT(p); } order--; // Check length len= ((char*)p)-((char*)q); if (len != FFCSIZE(n_head-1, n_val)) error("Internal error; bad call to stack_filter(); length mismatch (%d,%d)", len, FFCSIZE(n_head-1, n_val)); // Make as many additional copies as necessary while (order-- > 0) { memcpy(p, q, len); p= (void*)(len + (char*)p); } // List is already terminated due to zeroed allocation return rv; } // // Search for a peak between two given frequencies. It is // assumed that the gradient goes upwards from 'f0' to the peak, // and then down again to 'f3'. If there are any other curves, // this routine will get confused and will come up with some // frequency, although probably not the right one. // // Returns the frequency of the peak. // static double search_peak(FidFilter *ff, double f0, double f3) { double f1, f2; double r1, r2; int a; // Binary search, modified, taking two intermediate points. Do 20 // subdivisions, which should give 1/2^20 == 1e-6 accuracy compared // to original range. for (a= 0; a<20; a++) { f1= 0.51 * f0 + 0.49 * f3; f2= 0.49 * f0 + 0.51 * f3; if (f1 == f2) break; // We're hitting FP limit r1= fid_response(ff, f1); r2= fid_response(ff, f2); if (r1 > r2) // Peak is either to the left, or between f1/f2 f3= f2; else // Peak is either to the right, or between f1/f2 f0= f1; } return (f0+f3)*0.5; } // // Handle the different 'back-ends' for Bessel, Butterworth and // Chebyshev filters. First argument selects between bilinear // (0) and matched-Z (non-0). The BL and MZ macros makes this a // bit more obvious in the code. // // Overall filter gain is adjusted to give the peak at 1.0. This // is easy for all types except for band-pass, where a search is // required to find the precise peak. This is much slower than // the other types. // #define BL 0 #define MZ 1 static FidFilter* do_lowpass(int mz, double freq) { FidFilter *rv; lowpass(prewarp(freq)); if (mz) s2z_matchedZ(); else s2z_bilinear(); rv= z2fidfilter(1.0, ~0); // FIR is constant rv->val[0]= 1.0 / fid_response(rv, 0.0); return rv; } static FidFilter* do_highpass(int mz, double freq) { FidFilter *rv; highpass(prewarp(freq)); if (mz) s2z_matchedZ(); else s2z_bilinear(); rv= z2fidfilter(1.0, ~0); // FIR is constant rv->val[0]= 1.0 / fid_response(rv, 0.5); return rv; } static FidFilter* do_bandpass(int mz, double f0, double f1) { FidFilter *rv; bandpass(prewarp(f0), prewarp(f1)); if (mz) s2z_matchedZ(); else s2z_bilinear(); rv= z2fidfilter(1.0, ~0); // FIR is constant rv->val[0]= 1.0 / fid_response(rv, search_peak(rv, f0, f1)); return rv; } static FidFilter* do_bandstop(int mz, double f0, double f1) { FidFilter *rv; bandstop(prewarp(f0), prewarp(f1)); if (mz) s2z_matchedZ(); else s2z_bilinear(); rv= z2fidfilter(1.0, 5); // FIR second coefficient is *non-const* for bandstop rv->val[0]= 1.0 / fid_response(rv, 0.0); // Use 0Hz response as reference return rv; } // // Information passed to individual filter design routines: // // double* rout(double rate, double f0, double f1, // int order, int n_arg, double *arg); // // 'rate' is the sampling rate, or 1 if not set // 'f0' and 'f1' give the frequency or frequency range as a // proportion of the sampling rate // 'order' is the order of the filter (the integer passed immediately // after the name) // 'n_arg' is the number of additional arguments for the filter // 'arg' gives the additional argument values: arg[n] // // Note that #O #o #F and #R are mapped to the f0/f1/order // arguments, and are not included in the arg[] array. // // See the previous description for the required meaning of the // return value FidFilter list. // // // Filter design routines and supporting code // static FidFilter* des_bpre(double rate, double f0, double f1, int order, int n_arg, double *arg) { bandpass_res(f0, arg[0]); return z2fidfilter(1.0, ~0); // FIR constant } static FidFilter* des_bsre(double rate, double f0, double f1, int order, int n_arg, double *arg) { bandstop_res(f0, arg[0]); return z2fidfilter(1.0, 0); // FIR not constant, depends on freq } static FidFilter* des_apre(double rate, double f0, double f1, int order, int n_arg, double *arg) { allpass_res(f0, arg[0]); return z2fidfilter(1.0, 0); // FIR not constant, depends on freq } static FidFilter* des_pi(double rate, double f0, double f1, int order, int n_arg, double *arg) { prop_integral(prewarp(f0)); s2z_bilinear(); return z2fidfilter(1.0, 0); // FIR not constant, depends on freq } static FidFilter* des_piz(double rate, double f0, double f1, int order, int n_arg, double *arg) { prop_integral(prewarp(f0)); s2z_matchedZ(); return z2fidfilter(1.0, 0); // FIR not constant, depends on freq } static FidFilter* des_lpbe(double rate, double f0, double f1, int order, int n_arg, double *arg) { bessel(order); return do_lowpass(BL, f0); } static FidFilter* des_hpbe(double rate, double f0, double f1, int order, int n_arg, double *arg) { bessel(order); return do_highpass(BL, f0); } static FidFilter* des_bpbe(double rate, double f0, double f1, int order, int n_arg, double *arg) { bessel(order); return do_bandpass(BL, f0, f1); } static FidFilter* des_bsbe(double rate, double f0, double f1, int order, int n_arg, double *arg) { bessel(order); return do_bandstop(BL, f0, f1); } static FidFilter* des_lpbez(double rate, double f0, double f1, int order, int n_arg, double *arg) { bessel(order); return do_lowpass(MZ, f0); } static FidFilter* des_hpbez(double rate, double f0, double f1, int order, int n_arg, double *arg) { bessel(order); return do_highpass(MZ, f0); } static FidFilter* des_bpbez(double rate, double f0, double f1, int order, int n_arg, double *arg) { bessel(order); return do_bandpass(MZ, f0, f1); } static FidFilter* des_bsbez(double rate, double f0, double f1, int order, int n_arg, double *arg) { bessel(order); return do_bandstop(MZ, f0, f1); } static FidFilter* // Butterworth-Bessel cross des_lpbube(double rate, double f0, double f1, int order, int n_arg, double *arg) { double tmp[MAXPZ]; int a; bessel(order); memcpy(tmp, pol, order * sizeof(double)); butterworth(order); for (a= 0; atyp= 'F'; ff->cbm= 0; ff->len= max*2+1; ff->val[max]= tot= 1.0; for (a= 1; a<=max; a++) { double val= 0.42 + 0.5 * cos(M_PI * a / wid) + 0.08 * cos(M_PI * 2.0 * a / wid); ff->val[max-a]= val; ff->val[max+a]= val; tot += val * 2.0; } adj= 1/tot; for (a= 0; a<=max*2; a++) ff->val[a] *= adj; return ff; } static FidFilter* des_lphm(double rate, double f0, double f1, int order, int n_arg, double *arg) { double wid= 0.3262096/f0; double tot, adj; int max= (int)floor(wid); int a; FidFilter *ff= Alloc(FFCSIZE(1, max*2+1)); ff->typ= 'F'; ff->cbm= 0; ff->len= max*2+1; ff->val[max]= tot= 1.0; for (a= 1; a<=max; a++) { double val= 0.54 + 0.46 * cos(M_PI * a / wid); ff->val[max-a]= val; ff->val[max+a]= val; tot += val * 2.0; } adj= 1/tot; for (a= 0; a<=max*2; a++) ff->val[a] *= adj; return ff; } static FidFilter* des_lphn(double rate, double f0, double f1, int order, int n_arg, double *arg) { double wid= 0.360144/f0; double tot, adj; int max= (int)floor(wid); int a; FidFilter *ff= Alloc(FFCSIZE(1, max*2+1)); ff->typ= 'F'; ff->cbm= 0; ff->len= max*2+1; ff->val[max]= tot= 1.0; for (a= 1; a<=max; a++) { double val= 0.5 + 0.5 * cos(M_PI * a / wid); ff->val[max-a]= val; ff->val[max+a]= val; tot += val * 2.0; } adj= 1/tot; for (a= 0; a<=max*2; a++) ff->val[a] *= adj; return ff; } static FidFilter* des_lpba(double rate, double f0, double f1, int order, int n_arg, double *arg) { double wid= 0.3189435/f0; double tot, adj; int max= (int)floor(wid); int a; FidFilter *ff= Alloc(FFCSIZE(1, max*2+1)); ff->typ= 'F'; ff->cbm= 0; ff->len= max*2+1; ff->val[max]= tot= 1.0; for (a= 1; a<=max; a++) { double val= 1.0 - a/wid; ff->val[max-a]= val; ff->val[max+a]= val; tot += val * 2.0; } adj= 1/tot; for (a= 0; a<=max*2; a++) ff->val[a] *= adj; return ff; } // // Filter table // static struct { FidFilter *(*rout)(double,double,double,int,int,double*); // Designer routine address char *fmt; // Format for spec-string char *txt; // Human-readable description of filter } filter[]= { { des_bpre, "BpRe/#V/#F", "Bandpass resonator, Q=#V (0 means Inf), frequency #F" }, { des_bsre, "BsRe/#V/#F", "Bandstop resonator, Q=#V (0 means Inf), frequency #F" }, { des_apre, "ApRe/#V/#F", "Allpass resonator, Q=#V (0 means Inf), frequency #F" }, { des_pi, "Pi/#F", "Proportional-integral filter, frequency #F" }, { des_piz, "PiZ/#F", "Proportional-integral filter, matched z-transform, frequency #F" }, { des_lpbe, "LpBe#O/#F", "Lowpass Bessel filter, order #O, -3.01dB frequency #F" }, { des_hpbe, "HpBe#O/#F", "Highpass Bessel filter, order #O, -3.01dB frequency #F" }, { des_bpbe, "BpBe#O/#R", "Bandpass Bessel filter, order #O, -3.01dB frequencies #R" }, { des_bsbe, "BsBe#O/#R", "Bandstop Bessel filter, order #O, -3.01dB frequencies #R" }, { des_lpbu, "LpBu#O/#F", "Lowpass Butterworth filter, order #O, -3.01dB frequency #F" }, { des_hpbu, "HpBu#O/#F", "Highpass Butterworth filter, order #O, -3.01dB frequency #F" }, { des_bpbu, "BpBu#O/#R", "Bandpass Butterworth filter, order #O, -3.01dB frequencies #R" }, { des_bsbu, "BsBu#O/#R", "Bandstop Butterworth filter, order #O, -3.01dB frequencies #R" }, { des_lpch, "LpCh#O/#V/#F", "Lowpass Chebyshev filter, order #O, passband ripple #VdB, -3.01dB frequency #F" }, { des_hpch, "HpCh#O/#V/#F", "Highpass Chebyshev filter, order #O, passband ripple #VdB, -3.01dB frequency #F" }, { des_bpch, "BpCh#O/#V/#R", "Bandpass Chebyshev filter, order #O, passband ripple #VdB, -3.01dB frequencies #R" }, { des_bsch, "BsCh#O/#V/#R", "Bandstop Chebyshev filter, order #O, passband ripple #VdB, -3.01dB frequencies #R" }, { des_lpbez, "LpBeZ#O/#F", "Lowpass Bessel filter, matched z-transform, order #O, -3.01dB frequency #F" }, { des_hpbez, "HpBeZ#O/#F", "Highpass Bessel filter, matched z-transform, order #O, -3.01dB frequency #F" }, { des_bpbez, "BpBeZ#O/#R", "Bandpass Bessel filter, matched z-transform, order #O, -3.01dB frequencies #R" }, { des_bsbez, "BsBeZ#O/#R", "Bandstop Bessel filter, matched z-transform, order #O, -3.01dB frequencies #R" }, { des_lpbuz, "LpBuZ#O/#F", "Lowpass Butterworth filter, matched z-transform, order #O, -3.01dB frequency #F" }, { des_hpbuz, "HpBuZ#O/#F", "Highpass Butterworth filter, matched z-transform, order #O, -3.01dB frequency #F" }, { des_bpbuz, "BpBuZ#O/#R", "Bandpass Butterworth filter, matched z-transform, order #O, -3.01dB frequencies #R" }, { des_bsbuz, "BsBuZ#O/#R", "Bandstop Butterworth filter, matched z-transform, order #O, -3.01dB frequencies #R" }, { des_lpchz, "LpChZ#O/#V/#F", "Lowpass Chebyshev filter, matched z-transform, order #O, " "passband ripple #VdB, -3.01dB frequency #F" }, { des_hpchz, "HpChZ#O/#V/#F", "Highpass Chebyshev filter, matched z-transform, order #O, " "passband ripple #VdB, -3.01dB frequency #F" }, { des_bpchz, "BpChZ#O/#V/#R", "Bandpass Chebyshev filter, matched z-transform, order #O, " "passband ripple #VdB, -3.01dB frequencies #R" }, { des_bschz, "BsChZ#O/#V/#R", "Bandstop Chebyshev filter, matched z-transform, order #O, " "passband ripple #VdB, -3.01dB frequencies #R" }, { des_lpbube, "LpBuBe#O/#V/#F", "Lowpass Butterworth-Bessel #V% cross, order #O, -3.01dB frequency #F" }, { des_lpbq, "LpBq#o/#V/#F", "Lowpass biquad filter, order #O, Q=#V, -3.01dB frequency #F" }, { des_hpbq, "HpBq#o/#V/#F", "Highpass biquad filter, order #O, Q=#V, -3.01dB frequency #F" }, { des_bpbq, "BpBq#o/#V/#F", "Bandpass biquad filter, order #O, Q=#V, centre frequency #F" }, { des_bsbq, "BsBq#o/#V/#F", "Bandstop biquad filter, order #O, Q=#V, centre frequency #F" }, { des_apbq, "ApBq#o/#V/#F", "Allpass biquad filter, order #O, Q=#V, centre frequency #F" }, { des_pkbq, "PkBq#o/#V/#V/#F", "Peaking biquad filter, order #O, Q=#V, dBgain=#V, frequency #F" }, { des_lsbq, "LsBq#o/#V/#V/#F", "Lowpass shelving biquad filter, S=#V, dBgain=#V, frequency #F" }, { des_hsbq, "HsBq#o/#V/#V/#F", "Highpass shelving biquad filter, S=#V, dBgain=#V, frequency #F" }, { des_lpbl, "LpBl/#F", "Lowpass Blackman window, -3.01dB frequency #F" }, { des_lphm, "LpHm/#F", "Lowpass Hamming window, -3.01dB frequency #F" }, { des_lphn, "LpHn/#F", "Lowpass Hann window, -3.01dB frequency #F" }, { des_lpba, "LpBa/#F", "Lowpass Bartlet (triangular) window, -3.01dB frequency #F" }, { 0, 0, 0 } }; // // Design a filter. Spec and range are passed as arguments. The // return value is a pointer to a FidFilter as documented earlier // in this file. This needs to be free()d once finished with. // // If 'f_adj' is set, then the frequencies fed to the design code // are adjusted automatically to get true sqrt(0.5) (-3.01dB) // values at the provided frequencies. (This is obviously a // slower operation) // // If 'descp' is non-0, then a long description of the filter is // generated and returned as a strdup'd string at the given // location. // // Any problem with the spec causes the program to die with an // error message. // // 'spec' gives the specification string. The 'rate' argument // gives the sampling rate for the data that will be passed to // the filter. This is only used to interpret the frequencies // given in the spec or given in 'freq0' and 'freq1'. Use 1.0 if // the frequencies are given as a proportion of the sampling // rate, in the range 0 to 0.5. 'freq0' and 'freq1' provide the // default frequency or frequency range if this is not included // in the specification string. These should be -ve if there is // no default range (causing an error if they are omitted from // the 'spec'). // typedef struct Spec Spec; static char* parse_spec(Spec*); static FidFilter *auto_adjust_single(Spec *sp, double rate, double f0); static FidFilter *auto_adjust_dual(Spec *sp, double rate, double f0, double f1); struct Spec { #define MAXARG 10 char *spec; double in_f0, in_f1; int in_adj; double argarr[MAXARG]; double f0, f1; int adj; int n_arg; int order; int minlen; // Minimum length of spec-string, assuming f0/f1 passed separately int n_freq; // Number of frequencies provided: 0,1,2 int fi; // Filter index (filter[fi]) }; FidFilter * fid_design(char *spec, double rate, double freq0, double freq1, int f_adj, char **descp) { FidFilter *rv; Spec sp; double f0, f1; char *err; // Parse the filter-spec sp.spec= spec; sp.in_f0= freq0; sp.in_f1= freq1; sp.in_adj= f_adj; err= parse_spec(&sp); if (err) error("%s", err); f0= sp.f0; f1= sp.f1; // Adjust frequencies to range 0-0.5, and check them f0 /= rate; if (f0 > 0.5) error("Frequency of %gHz out of range with sampling rate of %gHz", f0*rate, rate); f1 /= rate; if (f1 > 0.5) error("Frequency of %gHz out of range with sampling rate of %gHz", f1*rate, rate); // Okay we now have a successful spec-match to filter[sp.fi], and sp.n_arg // args are now in sp.argarr[] // Generate the filter if (!sp.adj) rv= filter[sp.fi].rout(rate, f0, f1, sp.order, sp.n_arg, sp.argarr); else if (strstr(filter[sp.fi].fmt, "#R")) rv= auto_adjust_dual(&sp, rate, f0, f1); else rv= auto_adjust_single(&sp, rate, f0); // Generate a long description if required if (descp) { char *fmt= filter[sp.fi].txt; int max= strlen(fmt) + 60 + sp.n_arg * 20; char *desc= Alloc(max); char *p= desc; char ch; double *arg= sp.argarr; int n_arg= sp.n_arg; while ((ch= *fmt++)) { if (ch != '#') { *p++= ch; continue; } switch (*fmt++) { case 'O': p += sprintf(p, "%d", sp.order); break; case 'F': p += sprintf(p, "%g", f0*rate); break; case 'R': p += sprintf(p, "%g-%g", f0*rate, f1*rate); break; case 'V': if (n_arg <= 0) error("Internal error -- disagreement between filter short-spec\n" " and long-description over number of arguments"); n_arg--; p += sprintf(p, "%g", *arg++); break; default: error("Internal error: unknown format in long description: #%c", fmt[-1]); } } *p++= 0; if (p-desc >= max) error("Internal error: exceeded estimated description buffer"); *descp= desc; } return rv; } // // Auto-adjust input frequency to give correct sqrt(0.5) // (~-3.01dB) point to 6 figures // #define M301DB (0.707106781186548) static FidFilter * auto_adjust_single(Spec *sp, double rate, double f0) { double a0, a1, a2; FidFilter *(*design)(double,double,double,int,int,double*)= filter[sp->fi].rout; FidFilter *rv= 0; double resp; double r0, r2; int incr; // Increasing (1) or decreasing (0) int a; #define DESIGN(aa) design(rate, aa, aa, sp->order, sp->n_arg, sp->argarr) #define TEST(aa) { if (rv) {free(rv);rv= 0;} rv= DESIGN(aa); resp= fid_response(rv, f0); } // Try and establish a range within which we can find the point a0= f0; TEST(a0); r0= resp; for (a= 2; 1; a*=2) { a2= f0/a; TEST(a2); r2= resp; if ((r0 < M301DB) != (r2 < M301DB)) break; a2= 0.5-((0.5-f0)/a); TEST(a2); r2= resp; if ((r0 < M301DB) != (r2 < M301DB)) break; if (a == 32) // No success error("auto_adjust_single internal error -- can't establish enclosing range"); } incr= r2 > r0; if (a0 > a2) { a1= a0; a0= a2; a2= a1; incr= !incr; } // Binary search while (1) { a1= 0.5 * (a0 + a2); if (a1 == a0 || a1 == a2) break; // Limit of double, sanity check TEST(a1); if (resp >= 0.9999995 * M301DB && resp < 1.0000005 * M301DB) break; if (incr == (resp > M301DB)) a2= a1; else a0= a1; } #undef TEST #undef DESIGN return rv; } // // Auto-adjust input frequencies to give response of sqrt(0.5) // (~-3.01dB) correct to 6sf at the given frequency-points // static FidFilter * auto_adjust_dual(Spec *sp, double rate, double f0, double f1) { double mid= 0.5 * (f0+f1); double wid= 0.5 * fabs(f1-f0); FidFilter *(*design)(double,double,double,int,int,double*)= filter[sp->fi].rout; FidFilter *rv= 0; int bpass= -1; double delta; double mid0, mid1; double wid0, wid1; double r0, r1, err0, err1; double perr; int cnt; int cnt_design= 0; #define DESIGN(mm,ww) { if (rv) {free(rv);rv= 0;} \ rv= design(rate, mm-ww, mm+ww, sp->order, sp->n_arg, sp->argarr); \ r0= fid_response(rv, f0); r1= fid_response(rv, f1); \ err0= fabs(M301DB-r0); err1= fabs(M301DB-r1); cnt_design++; } #define INC_WID ((r0+r1 < 1.0) == bpass) #define INC_MID ((r0 > r1) == bpass) #define MATCH (err0 < 0.000000499 && err1 < 0.000000499) #define PERR (err0+err1) DESIGN(mid, wid); bpass= (fid_response(rv, 0) < 0.5); delta= wid * 0.5; // Try delta changes until we get there for (cnt= 0; 1; cnt++, delta *= 0.51) { DESIGN(mid, wid); // I know -- this is redundant perr= PERR; mid0= mid; wid0= wid; mid1= mid + (INC_MID ? delta : -delta); wid1= wid + (INC_WID ? delta : -delta); if (mid0 - wid1 > 0.0 && mid0 + wid1 < 0.5) { DESIGN(mid0, wid1); if (MATCH) break; if (PERR < perr) { perr= PERR; mid= mid0; wid= wid1; } } if (mid1 - wid0 > 0.0 && mid1 + wid0 < 0.5) { DESIGN(mid1, wid0); if (MATCH) break; if (PERR < perr) { perr= PERR; mid= mid1; wid= wid0; } } if (mid1 - wid1 > 0.0 && mid1 + wid1 < 0.5) { DESIGN(mid1, wid1); if (MATCH) break; if (PERR < perr) { perr= PERR; mid= mid1; wid= wid1; } } if (cnt > 1000) error("auto_adjust_dual -- design not converging"); } #undef INC_WID #undef INC_MID #undef MATCH #undef PERR #undef DESIGN return rv; } // // Expand a specification string to the given buffer; if out of // space, drops dead // static void expand_spec(char *buf, char *bufend, char *str) { int ch; char *p= buf; while ((ch= *str++)) { if (p + 10 >= bufend) error("Buffer overflow in fidlib expand_spec()"); if (ch == '#') { switch (*str++) { case 'o': p += sprintf(p, ""); break; case 'O': p += sprintf(p, ""); break; case 'F': p += sprintf(p, ""); break; case 'R': p += sprintf(p, ""); break; case 'V': p += sprintf(p, ""); break; default: p += sprintf(p, "<%c>", str[-1]); break; } } else { *p++= ch; } } *p= 0; } // // Design a filter and reduce it to a list of all the non-const // coefficients. Arguments are as for fid_filter(). The // coefficients are written into the given double array. If the // number of coefficients doesn't match the array length given, // then a fatal error is generated. // // Note that all 1-element FIRs and IIR first-coefficients are // merged into a single gain coefficient, which is returned // rather than being included in the coefficient list. This is // to allow it to be merged with other gains within a stack of // filters. // // The algorithm used here (merging 1-element FIRs and adjusting // IIR first-coefficients) must match that used in the code- // generating code, or else the coefficients won't match up. The // 'n_coef' argument provides a partial safeguard. // double fid_design_coef(double *coef, int n_coef, char *spec, double rate, double freq0, double freq1, int adj) { FidFilter *filt= fid_design(spec, rate, freq0, freq1, adj, 0); FidFilter *ff= filt; int a, len; int cnt= 0; double gain= 1.0; double *iir, *fir, iir_adj; static double const_one= 1; int n_iir, n_fir; int iir_cbm, fir_cbm; while (ff->typ) { if (ff->typ == 'F' && ff->len == 1) { gain *= ff->val[0]; ff= FFNEXT(ff); continue; } if (ff->typ != 'I' && ff->typ != 'F') error("fid_design_coef can't handle FidFilter type: %c", ff->typ); // Initialise to safe defaults iir= fir= &const_one; n_iir= n_fir= 1; iir_cbm= fir_cbm= ~0; // See if we have an IIR filter if (ff->typ == 'I') { iir= ff->val; n_iir= ff->len; iir_cbm= ff->cbm; iir_adj= 1.0 / ff->val[0]; ff= FFNEXT(ff); gain *= iir_adj; } // See if we have an FIR filter if (ff->typ == 'F') { fir= ff->val; n_fir= ff->len; fir_cbm= ff->cbm; ff= FFNEXT(ff); } // Dump out all non-const coefficients in reverse order len= n_fir > n_iir ? n_fir : n_iir; for (a= len-1; a>=0; a--) { // Output IIR if present and non-const if (a < n_iir && a>0 && !(iir_cbm & (1<<(a<15?a:15)))) { if (cnt++ < n_coef) *coef++= iir_adj * iir[a]; } // Output FIR if present and non-const if (a < n_fir && !(fir_cbm & (1<<(a<15?a:15)))) { if (cnt++ < n_coef) *coef++= fir[a]; } } } if (cnt != n_coef) error("fid_design_coef called with the wrong number of coefficients.\n" " Given %d, expecting %d: (\"%s\",%g,%g,%g,%d)", n_coef, cnt, spec, rate, freq0, freq1, adj); free(filt); return gain; } // // List all the known filters to the given file handle // void fid_list_filters(FILE *out) { int a; for (a= 0; filter[a].fmt; a++) { char buf[4096]; expand_spec(buf, buf+sizeof(buf), filter[a].fmt); fprintf(out, "%s\n ", buf); expand_spec(buf, buf+sizeof(buf), filter[a].txt); fprintf(out, "%s\n", buf); } } // // List all the known filters to the given buffer; the buffer is // NUL-terminated; returns 1 okay, 0 not enough space // int fid_list_filters_buf(char *buf, char *bufend) { int a, cnt; char tmp[4096]; for (a= 0; filter[a].fmt; a++) { expand_spec(tmp, tmp+sizeof(tmp), filter[a].fmt); buf += (cnt= snprintf(buf, bufend-buf, "%s\n ", tmp)); if (cnt < 0 || buf >= bufend) return 0; expand_spec(tmp, tmp+sizeof(tmp), filter[a].txt); buf += (cnt= snprintf(buf, bufend-buf, "%s\n", tmp)); if (cnt < 0 || buf >= bufend) return 0; } return 1; } // // Do a convolution of parameters in place // STATIC_INLINE int convolve(double *dst, int n_dst, double *src, int n_src) { int len= n_dst + n_src - 1; int a, b; for (a= len-1; a>=0; a--) { double val= 0; for (b= 0; b= 0 && a-b < n_dst) val += src[b] * dst[a-b]; dst[a]= val; } return len; } // // Generate a combined filter -- merge all the IIR/FIR // sub-filters into a single IIR/FIR pair, and make sure the IIR // first coefficient is 1.0. // FidFilter * fid_flatten(FidFilter *filt) { int m_fir= 1; // Maximum values int m_iir= 1; int n_fir, n_iir; // Stored counts during convolution FidFilter *ff; FidFilter *rv; double *fir, *iir; double adj; int a; // Find the size of the output filter ff= filt; while (ff->len) { if (ff->typ == 'I') m_iir += ff->len-1; else if (ff->typ == 'F') m_fir += ff->len-1; else error("fid_flatten doesn't know about type %d", ff->typ); ff= FFNEXT(ff); } // Setup the output array rv= FFALLOC(2, m_iir + m_fir); rv->typ= 'I'; rv->len= m_iir; iir= rv->val; ff= FFNEXT(rv); ff->typ= 'F'; ff->len= m_fir; fir= ff->val; iir[0]= 1.0; n_iir= 1; fir[0]= 1.0; n_fir= 1; // Do the convolution ff= filt; while (ff->len) { if (ff->typ == 'I') n_iir= convolve(iir, n_iir, ff->val, ff->len); else n_fir= convolve(fir, n_fir, ff->val, ff->len); ff= FFNEXT(ff); } // Sanity check if (n_iir != m_iir || n_fir != m_fir) error("Internal error in fid_combine() -- array under/overflow"); // Fix iir[0] adj= 1.0/iir[0]; for (a= 0; aargarr; sp->n_arg= 0; sp->order= 0; sp->f0= 0; sp->f1= 0; sp->adj= 0; sp->minlen= -1; sp->n_freq= 0; for (a= 0; 1; a++) { char *fmt= filter[a].fmt; char *p= sp->spec; char ch, *q; if (!fmt) return strdupf("Spec-string \"%s\" matches no known format", sp->spec); while (*p && (ch= *fmt++)) { if (ch != '#') { if (ch == *p++) continue; p= 0; break; } if (isalpha(*p)) { p= 0; break; } // Handling a format character switch (ch= *fmt++) { default: return strdupf("Internal error: Unknown format #%c in format: %s", fmt[-1], filter[a].fmt); case 'o': case 'O': sp->order= (int)strtol(p, &q, 10); if (p == q) { if (ch == 'O') goto bad; sp->order= 1; } if (sp->order <= 0) return strdupf("Bad order %d in spec-string \"%s\"", sp->order, sp->spec); p= q; break; case 'V': sp->n_arg++; *arg++= strtod(p, &q); if (p == q) goto bad; p= q; break; case 'F': sp->minlen= p-1-sp->spec; sp->n_freq= 1; sp->adj= (p[0] == '='); if (sp->adj) p++; sp->f0= strtod(p, &q); sp->f1= 0; if (p == q) goto bad; p= q; break; case 'R': sp->minlen= p-1-sp->spec; sp->n_freq= 2; sp->adj= (p[0] == '='); if (sp->adj) p++; sp->f0= strtod(p, &q); if (p == q) goto bad; p= q; if (*p++ != '-') goto bad; sp->f1= strtod(p, &q); if (p == q) goto bad; if (sp->f0 > sp->f1) return strdupf("Backwards frequency range in spec-string \"%s\"", sp->spec); p= q; break; } } if (p == 0) continue; if (fmt[0] == '/' && fmt[1] == '#' && fmt[2] == 'F') { sp->minlen= p-sp->spec; sp->n_freq= 1; if (sp->in_f0 < 0.0) return strdupf("Frequency omitted from filter-spec, and no default provided"); sp->f0= sp->in_f0; sp->f1= 0; sp->adj= sp->in_adj; fmt += 3; } else if (fmt[0] == '/' && fmt[1] == '#' && fmt[2] == 'R') { sp->minlen= p-sp->spec; sp->n_freq= 2; if (sp->in_f0 < 0.0 || sp->in_f1 < 0.0) return strdupf("Frequency omitted from filter-spec, and no default provided"); sp->f0= sp->in_f0; sp->f1= sp->in_f1; sp->adj= sp->in_adj; fmt += 3; } // Check for trailing unmatched format characters if (*fmt) { bad: return strdupf("Bad match of spec-string \"%s\" to format \"%s\"", sp->spec, filter[a].fmt); } if (sp->n_arg > MAXARG) return strdupf("Internal error -- maximum arguments exceeded"); // Set the minlen to the whole string if unset if (sp->minlen < 0) sp->minlen= p-sp->spec; // Save values, return sp->fi= a; return 0; } return 0; } // // Parse a filter-spec and freq0/freq1 arguments and rewrite them // to give an all-in-one filter spec and/or a minimum spec plus // separate freq0/freq1 arguments. The all-in-one spec is // returned in *spec1p (strdup'd), and the minimum separated-out // spec is returned in *spec2p (strdup'd), *freq0p and *freq1p. // If either of spec1p or spec2p is 0, then that particular // spec-string is not generated. // void fid_rewrite_spec(char *spec, double freq0, double freq1, int adj, char **spec1p, char **spec2p, double *freq0p, double *freq1p, int *adjp) { Spec sp; char *err; sp.spec= spec; sp.in_f0= freq0; sp.in_f1= freq1; sp.in_adj= adj; err= parse_spec(&sp); if (err) error("%s", err); if (spec1p) { char buf[128]; int len; char *rv; switch (sp.n_freq) { case 1: sprintf(buf, "/%s%.15g", sp.adj ? "=" : "", sp.f0); break; case 2: sprintf(buf, "/%s%.15g-%.15g", sp.adj ? "=" : "", sp.f0, sp.f1); break; default: buf[0]= 0; } len= strlen(buf); rv= Alloc(sp.minlen + len + 1); memcpy(rv, spec, sp.minlen); strcpy(rv+sp.minlen, buf); *spec1p= rv; } if (spec2p) { char *rv= Alloc(sp.minlen + 1); memcpy(rv, spec, sp.minlen); *spec2p= rv; *freq0p= sp.f0; *freq1p= sp.f1; *adjp= sp.adj; } } // // Create a FidFilter from the given double array. The double[] // should contain one or more sections, each starting with the // filter type (either 'I' or 'F', as a double), then a count of // the number of coefficients following, then the coefficients // themselves. The end of the list is marked with a type of 0. // // This is really just a convenience function, allowing a filter // to be conveniently dumped to C source code and then // reconstructed. // // Note that for more general filter generation, FidFilter // instances can be created simply by allocating the memory and // filling them in (see fidlib.h). // FidFilter * fid_cv_array(double *arr) { double *dp; FidFilter *ff, *rv; int n_head= 0; int n_val= 0; // Scan through for sizes for (dp= arr; *dp; ) { int len, typ; typ= (int)(*dp++); if (typ != 'F' && typ != 'I') error("Bad type in array passed to fid_cv_array: %g", dp[-1]); len= (int)(*dp++); if (len < 1) error("Bad length in array passed to fid_cv_array: %g", dp[-1]); n_head++; n_val += len; dp += len; } rv= ff= Alloc(FFCSIZE(n_head, n_val)); // Scan through to fill in FidFilter for (dp= arr; *dp; ) { int len, typ; typ= (int)(*dp++); len= (int)(*dp++); ff->typ= typ; ff->cbm= ~0; ff->len= len; memcpy(ff->val, dp, len * sizeof(double)); dp += len; ff= FFNEXT(ff); } // Final element already zero'd thanks to allocation return rv; } // // Create a single filter from the given list of filters in // order. If 'freeme' is set, then all the listed filters are // free'd once read; otherwise they are left untouched. The // newly allocated resultant filter is returned, which should be // released with free() when finished with. // FidFilter * fid_cat(int freeme, ...) { va_list ap; FidFilter *rv, *ff, *ff0; int len= 0; int cnt; char *dst; // Find the memory required to store the combined filter va_start(ap, freeme); while ((ff0= va_arg(ap, FidFilter*))) { for (ff= ff0; ff->typ; ff= FFNEXT(ff)) ; len += ((char*)ff) - ((char*)ff0); } va_end(ap); rv= Alloc(FFCSIZE(0,0) + len); dst= (char*)rv; va_start(ap, freeme); while ((ff0= va_arg(ap, FidFilter*))) { for (ff= ff0; ff->typ; ff= FFNEXT(ff)) ; cnt= ((char*)ff) - ((char*)ff0); memcpy(dst, ff0, cnt); dst += cnt; if (freeme) free(ff0); } va_end(ap); // Final element already zero'd return rv; } // // Support for fid_parse // // Skip white space (including comments) static void skipWS(char **pp) { char *p= *pp; while (*p) { if (isspace(*p)) { p++; continue; } if (*p == '#') { while (*p && *p != '\n') p++; continue; } break; } *pp= p; } // Grab a word from the input into the given buffer. Returns 0: end // of file or error, else 1: success. Error is indicated when the // word doesn't fit in the buffer. static int grabWord(char **pp, char *buf, int buflen) { char *p, *q; int len; skipWS(pp); p= *pp; if (!*p) return 0; q= p; if (*q == ',' || *q == ';' || *q == ')' || *q == ']' || *q == '}') { q++; } else { while (*q && *q != '#' && !isspace(*q) && (*q != ',' && *q != ';' && *q != ')' && *q != ']' && *q != '}')) q++; } len= q-p; if (len >= buflen) return 0; memcpy(buf, p, len); buf[len]= 0; *pp= q; return 1; } // // Parse an entire filter specification, perhaps consisting of // several FIR, IIR and predefined filters. Stops at the first // ,; or unmatched )]}. Returns either 0 on success, or else a // strdup'd error string. // // This duplicates code from Fiview filter.c, I know, but this // may have to expand in the future to handle '+' operations, and // special filter types like tunable heterodyne filters. At that // point, the filter.c code will have to be modified to call a // version of this routine. // char * fid_parse(double rate, char **pp, FidFilter **ffp) { char buf[128]; char *p= *pp, *rew; #define INIT_LEN 128 char *rv= Alloc(INIT_LEN); char *rvend= rv + INIT_LEN; char *rvp= rv; char *tmp; #undef INIT_LEN FidFilter *curr; int xtra= FFCSIZE(0,0); int typ= -1; // First time through double val; char dmy; #define ERR(ptr, msg) { *pp= ptr; *ffp= 0; return msg; } #define INCBUF { tmp= realloc(rv, (rvend-rv) * 2); if (!tmp) error("Out of memory"); \ rvend= (rvend-rv) * 2 + tmp; rvp= (rvp-rv) + tmp; \ curr= (void*)(((char*)curr) - rv + tmp); rv= tmp; } while (1) { rew= p; if (!grabWord(&p, buf, sizeof(buf))) { if (*p) ERR(p, strdupf("Filter element unexpectedly long -- syntax error?")); buf[0]= 0; } if (!buf[0] || !buf[1]) switch (buf[0]) { default: break; case 0: case ',': case ';': case ')': case ']': case '}': // End of filter, return it tmp= realloc(rv, (rvp-rv) + xtra); if (!tmp) error("Out of memory"); curr= (void*)((rvp-rv) + tmp); curr->typ= 0; curr->cbm= 0; curr->len= 0; *pp= buf[0] ? (p-1) : p; *ffp= (FidFilter*)tmp; return 0; case '/': if (typ > 0) ERR(rew, strdupf("Filter syntax error; unexpected '/'")); typ= 'I'; continue; case 'x': if (typ > 0) ERR(rew, strdupf("Filter syntax error; unexpected 'x'")); typ= 'F'; continue; } if (typ < 0) typ= 'F'; // Assume 'x' if missing if (!typ) ERR(p, strdupf("Expecting a 'x' or '/' before this")); if (1 != sscanf(buf, "%lf %c", &val, &dmy)) { // Must be a predefined filter FidFilter *ff; FidFilter *ff1; Spec sp; double f0, f1; char *err; int len; if (typ != 'F') ERR(rew, strdupf("Predefined filters cannot be used with '/'")); // Parse the filter-spec memset(&sp, 0, sizeof(sp)); sp.spec= buf; sp.in_f0= sp.in_f1= -1; if ((err= parse_spec(&sp))) ERR(rew, err); f0= sp.f0; f1= sp.f1; // Adjust frequencies to range 0-0.5, and check them f0 /= rate; if (f0 > 0.5) ERR(rew, strdupf("Frequency of %gHz out of range with " "sampling rate of %gHz", f0*rate, rate)); f1 /= rate; if (f1 > 0.5) ERR(rew, strdupf("Frequency of %gHz out of range with " "sampling rate of %gHz", f1*rate, rate)); // Okay we now have a successful spec-match to filter[sp.fi], and sp.n_arg // args are now in sp.argarr[] // Generate the filter if (!sp.adj) ff= filter[sp.fi].rout(rate, f0, f1, sp.order, sp.n_arg, sp.argarr); else if (strstr(filter[sp.fi].fmt, "#R")) ff= auto_adjust_dual(&sp, rate, f0, f1); else ff= auto_adjust_single(&sp, rate, f0); // Append it to our FidFilter to return for (ff1= ff; ff1->typ; ff1= FFNEXT(ff1)) ; len= ((char*)ff1-(char*)ff); while (rvp + len + xtra >= rvend) INCBUF; memcpy(rvp, ff, len); rvp += len; free(ff); typ= 0; continue; } // Must be a list of coefficients curr= (void*)rvp; rvp += xtra; while (rvp + sizeof(double) >= rvend) INCBUF; curr->typ= typ; curr->cbm= ~0; curr->len= 1; *(double*)rvp= val; rvp += sizeof(double); // See how many more coefficients we can pick up while (1) { rew= p; if (!grabWord(&p, buf, sizeof(buf))) { if (*p) ERR(p, strdupf("Filter element unexpectedly long -- syntax error?")); buf[0]= 0; } if (1 != sscanf(buf, "%lf %c", &val, &dmy)) { p= rew; break; } while (rvp + sizeof(double) >= rvend) INCBUF; curr->len++; *(double*)rvp= val; rvp += sizeof(double); } typ= 0; continue; } #undef INCBUF #undef ERR return strdupf("Internal error, shouldn't reach here"); } // // Filter-running code // #ifdef RF_COMBINED #include "fidrf_combined.h" #endif #ifdef RF_CMDLIST #include "fidrf_cmdlist.h" #endif #ifdef RF_JIT #include "fidrf_jit.h" #endif // END // edfbrowser_153_source/third_party/fidlib/PaxHeaders.2978/fidrf_cmdlist.h0000644000175000001440000000013212251654530024713 xustar000000000000000030 mtime=1386699096.463032596 30 atime=1386699096.463032596 30 ctime=1386699096.463032596 edfbrowser_153_source/third_party/fidlib/fidrf_cmdlist.h0000644000175000001440000002756512251654530024463 0ustar00novarausers00000000000000// // Command-list based filter-running code. // // Copyright (c) 2002-2003 Jim Peters . This // file is released under the GNU Lesser General Public License // (LGPL) version 2.1 as published by the Free Software // Foundation. See the file COPYING_LIB for details, or visit // . // // This version of the filter-running code is based on getting // the filter to go as fast as possible with a pre-compiled // routine, but without flattening the filter structure. This // gives greater accuracy than the combined filter. The result // is mostly faster than the combined filter (tested on ix86 with // gcc -O6), except where the combined filter gets a big // advantage from flattening the filter list. This code is also // portable (unlike the JIT option). // typedef struct Run { int magic; // Magic: 0x64966325 int buf_size; // Length of working buffer required in doubles double *coef; // Coefficient list char *cmd; // Command list } Run; typedef struct RunBuf { double *coef; char *cmd; int mov_cnt; // Number of bytes to memmove double buf[0]; } RunBuf; // // Filter processing routine. This is designed to avoid too many // branches, and references are very localized in the code, // keeping the optimizer from trying to store and remember old // values. // // // Step commands: // 0 END // 1 IIR coefficient (1+0) // 2 2x IIR coefficient (2+0) // 3 3x IIR coefficient (3+0) // 4 4Nx IIR coefficient (4N+0) // 5 FIR coefficient (0+1) // 6 2x FIR coefficient (0+2) // 7 3x FIR coefficient (0+3) // 8 4Nx FIR coefficient (0+4N) // 9 IIR+FIR coefficients (1+1) // 10 2x IIR+FIR coefficients (2+2) // 11 3x IIR+FIR coefficients (3+3) // 12 4Nx IIR+FIR coefficients (4N+4N) // 13 End-stage, pure IIR, assume no FIR done at all (1+0) // 14 End-stage with just FIR coeff (0+2) // 15 End-stage with IIR+FIR coeff (1+2) // 16 IIR + pure-IIR endstage (2+0) // 17 FIR + FIR end-stage (0+3) // 18 IIR+FIR + IIR+FIR end-stage (2+3) // 19 Nx (IIR + pure-IIR endstage) (2+0) // 20 Nx (FIR + FIR end-stage) (0+3) // 21 Nx (IIR+FIR + IIR+FIR end-stage) (2+3) // 22 Gain coefficient (0+1) // // Most filters are made up of 2x2 IIR/FIR pairs, which means a // list of command 18 bytes. The other big job would be long FIR // filters. These have to be handled with a list of 7,6,5 // commands, plus a 13 command. // typedef unsigned char uchar; static double filter_step(void *fbuf, double iir) { double *coef= ((RunBuf*)fbuf)->coef; uchar *cmd= ((RunBuf*)fbuf)->cmd; double *buf= &((RunBuf*)fbuf)->buf[0]; uchar ch; double fir= 0; double tmp= buf[0]; int cnt; // Using a memmove first is faster on gcc -O6 / ix86 than moving // the values whilst working through the buffers. memmove(buf, buf+1, ((RunBuf*)fbuf)->mov_cnt); #define IIR \ iir -= *coef++ * tmp; \ tmp= *buf++; #define FIR \ fir += *coef++ * tmp; \ tmp= *buf++; #define BOTH \ iir -= *coef++ * tmp; \ fir += *coef++ * tmp; \ tmp= *buf++; #define ENDIIR \ iir -= *coef++ * tmp; \ tmp= *buf++; \ buf[-1]= iir; #define ENDFIR \ fir += *coef++ * tmp; \ tmp= *buf++; \ buf[-1]= iir; \ iir= fir + *coef++ * iir; \ fir= 0 #define ENDBOTH \ iir -= *coef++ * tmp; \ fir += *coef++ * tmp; \ tmp= *buf++; \ buf[-1]= iir; \ iir= fir + *coef++ * iir; \ fir= 0 #define GAIN \ iir *= *coef++ while ((ch= *cmd++)) switch (ch) { case 1: IIR; break; case 2: IIR; IIR; break; case 3: IIR; IIR; IIR; break; case 4: cnt= *cmd++; do { IIR; IIR; IIR; IIR; } while (--cnt > 0); break; case 5: FIR; break; case 6: FIR; FIR; break; case 7: FIR; FIR; FIR; break; case 8: cnt= *cmd++; do { FIR; FIR; FIR; FIR; } while (--cnt > 0); break; case 9: BOTH; break; case 10: BOTH; BOTH; break; case 11: BOTH; BOTH; BOTH; break; case 12: cnt= *cmd++; do { BOTH; BOTH; BOTH; BOTH; } while (--cnt > 0); break; case 13: ENDIIR; break; case 14: ENDFIR; break; case 15: ENDBOTH; break; case 16: IIR; ENDIIR; break; case 17: FIR; ENDFIR; break; case 18: BOTH; ENDBOTH; break; case 19: cnt= *cmd++; do { IIR; ENDIIR; } while (--cnt > 0); break; case 20: cnt= *cmd++; do { FIR; ENDFIR; } while (--cnt > 0); break; case 21: cnt= *cmd++; do { BOTH; ENDBOTH; } while (--cnt > 0); break; case 22: GAIN; break; } #undef IIR #undef FIR #undef BOTH #undef ENDIIR #undef ENDFIR #undef ENDBOTH #undef GAIN return iir; } // // Create an instance of a filter, ready to run. This returns a // void* handle, and a function to call to execute the filter. // Working buffers for the filter instances must be allocated // separately using fid_run_newbuf(). This allows many // simultaneous instances of the filter to be run. // // The sub-filters are executed in the precise order that they // are given. This may lead to some inefficiency. Normally when // an IIR filter is followed by an FIR filter, the buffers can be // shared. However, if the sub-filters are not in IIR/FIR pairs, // then extra memory accesses are required. // // In any case, factors are extracted from IIR filters (so that // the first coefficient is 1), and single-element FIR filters // are merged into the global gain factor, and are ignored. // // The returned handle must be released using fid_run_free(). // void * fid_run_new(FidFilter *filt, double (**funcpp)(void *,double)) { int buf_size= 0; uchar *cp, prev; FidFilter *ff; double *dp; double gain= 1.0; int a; double *coef_tmp; uchar *cmd_tmp; int coef_cnt, coef_max; int cmd_cnt, cmd_max; int filt_cnt= 0; Run *rr; for (ff= filt; ff->len; ff= FFNEXT(ff)) filt_cnt += ff->len; // Allocate worst-case sizes for temporary arrays coef_tmp= ALLOC_ARR(coef_max= filt_cnt + 1, double); cmd_tmp= ALLOC_ARR(cmd_max= filt_cnt + 4, char); dp= coef_tmp; cp= cmd_tmp; prev= 0; // Generate command and coefficient lists while (filt->len) { int n_iir, n_fir, cnt; double *iir, *fir; double adj; if (filt->typ == 'F' && filt->len == 1) { gain *= filt->val[0]; filt= FFNEXT(filt); continue; } if (filt->typ == 'F') { iir= 0; n_iir= 0; fir= filt->val; n_fir= filt->len; filt= FFNEXT(filt); } else if (filt->typ == 'I') { iir= filt->val; n_iir= filt->len; fir= 0; n_fir= 0; filt= FFNEXT(filt); while (filt->typ == 'F' && filt->len == 1) { gain *= filt->val[0]; filt= FFNEXT(filt); } if (filt->typ == 'F') { fir= filt->val; n_fir= filt->len; filt= FFNEXT(filt); } } else error("Internal error: fid_run_new can only handle IIR + FIR types"); // Okay, we now have an IIR/FIR pair to process, possibly with // n_iir or n_fir == 0 if one half is missing cnt= n_iir > n_fir ? n_iir : n_fir; buf_size += cnt-1; if (n_iir) { adj= 1.0 / iir[0]; gain *= adj; } if (n_fir == 3 && n_iir == 3) { if (prev == 18) { cp[-1]= prev= 21; *cp++= 2; } else if (prev == 21) { cp[-1]++; } else *cp++= prev= 18; *dp++= iir[2]*adj; *dp++= fir[2]; *dp++= iir[1]*adj; *dp++= fir[1]; *dp++= fir[0]; } else if (n_fir == 3 && n_iir == 0) { if (prev == 17) { cp[-1]= prev= 20; *cp++= 2; } else if (prev == 20) { cp[-1]++; } else *cp++= prev= 17; *dp++= fir[2]; *dp++= fir[1]; *dp++= fir[0]; } else if (n_fir == 0 && n_iir == 3) { if (prev == 16) { cp[-1]= prev= 19; *cp++= 2; } else if (prev == 19) { cp[-1]++; } else *cp++= prev= 16; *dp++= iir[2]*adj; *dp++= iir[1]*adj; } else { prev= 0; // Just cancel 'prev' as we only use it for 16-18,19-21 if (cnt > n_fir) { a= 0; while (cnt > n_fir && cnt > 2) { *dp++= iir[--cnt] * adj; a++; } while (a >= 4) { int nn= a/4; if (nn > 255) nn= 255; *cp++= 4; *cp++= nn; a -= nn*4; } if (a) *cp++= a; } if (cnt > n_iir) { a= 0; while (cnt > n_iir && cnt > 2) { *dp++= fir[--cnt]; a++; } while (a >= 4) { int nn= a/4; if (nn > 255) nn= 255; *cp++= 8; *cp++= nn; a -= nn*4; } if (a) *cp++= 4+a; } a= 0; while (cnt > 2) { cnt--; a++; *dp++= iir[cnt]*adj; *dp++= fir[cnt]; } while (a >= 4) { int nn= a/4; if (nn > 255) nn= 255; *cp++= 12; *cp++= nn; a -= nn*4; } if (a) *cp++= 8+a; if (!n_fir) { *cp++= 13; *dp++= iir[1]; } else if (!n_iir) { *cp++= 14; *dp++= fir[1]; *dp++= fir[0]; } else { *cp++= 15; *dp++= iir[1]; *dp++= fir[1]; *dp++= fir[0]; } } } if (gain != 1.0) { *cp++= 22; *dp++= gain; } *cp++= 0; // Sanity checks coef_cnt= dp-coef_tmp; cmd_cnt= cp-cmd_tmp; if (coef_cnt > coef_max || cmd_cnt > cmd_max) error("fid_run_new internal error; arrays exceeded"); // Allocate the final Run structure to return rr= (Run*)Alloc(sizeof(Run) + coef_cnt*sizeof(double) + cmd_cnt*sizeof(char)); rr->magic= 0x64966325; rr->buf_size= buf_size; rr->coef= (double*)(rr+1); rr->cmd= (char*)(rr->coef + coef_cnt); memcpy(rr->coef, coef_tmp, coef_cnt*sizeof(double)); memcpy(rr->cmd, cmd_tmp, cmd_cnt*sizeof(char)); //DEBUG { //DEBUG int a; //DEBUG for (cp= cmd_tmp; *cp; cp++) printf("%d ", *cp); //DEBUG printf("\n"); //DEBUG //for (a= 0; amagic != 0x64966325) error("Bad handle passed to fid_run_newbuf()"); siz= rr->buf_size ? rr->buf_size : 1; // Minimum one element to avoid problems rb= Alloc(sizeof(RunBuf) + siz * sizeof(double)); rb->coef= rr->coef; rb->cmd= rr->cmd; rb->mov_cnt= (siz-1) * sizeof(double); // rb->buf[] already zerod return rb; } // // Find the space required for a filter buffer // int fid_run_bufsize(void *run) { Run *rr= run; int siz; if (rr->magic != 0x64966325) error("Bad handle passed to fid_run_bufsize()"); siz= rr->buf_size ? rr->buf_size : 1; // Minimum one element to avoid problems return sizeof(RunBuf) + siz * sizeof(double); } // // Initialise a filter buffer allocated separately. Usually // fid_run_newbuf() is easier, but in the case where filter // buffers must be allocated as part of a larger structure, a // call to fid_run_newbuf can be replaced with a call to // fid_run_bufsize() to get the space required, and then a call // to fid_run_initbuf() once it has been allocated. // void fid_run_initbuf(void *run, void *buf) { Run *rr= run; RunBuf *rb= buf; int siz; if (rr->magic != 0x64966325) error("Bad handle passed to fid_run_initbuf()"); siz= rr->buf_size ? rr->buf_size : 1; // Minimum one element to avoid problems rb->coef= rr->coef; rb->cmd= rr->cmd; rb->mov_cnt= (siz-1) * sizeof(double); memset(rb->buf, 0, rb->mov_cnt + sizeof(double)); } // // Reinitialise an instance of the filter, allowing it to start // afresh. It assumes that the buffer was correctly initialised // previously, either through a call to fid_run_newbuf() or // fid_run_initbuf(). // void fid_run_zapbuf(void *buf) { RunBuf *rb= buf; memset(rb->buf, 0, rb->mov_cnt + sizeof(double)); } // // Delete an instance // void fid_run_freebuf(void *runbuf) { free(runbuf); } // // Delete the filter // void fid_run_free(void *run) { free(run); } // END // edfbrowser_153_source/PaxHeaders.2978/disclaimer.txt0000644000175000001440000000013212251654530021024 xustar000000000000000030 mtime=1386699096.495032427 30 atime=1386699096.495032427 30 ctime=1386699096.495032427 edfbrowser_153_source/disclaimer.txt0000644000175000001440000000051012251654530020551 0ustar00novarausers00000000000000 This is free software, it is experimental and available under the GPL License version 2. Despite this software is intend to be useful, there is no warranty, use this software at your own risk! This software is intend to be used for education and/or research. DO NOT USE THIS SOFTWARE FOR MEDICAL PURPOSES AND/OR DIAGNOSIS! edfbrowser_153_source/PaxHeaders.2978/print_to_edf.cpp0000644000175000001440000000013212251654530021327 xustar000000000000000030 mtime=1386699096.478032517 30 atime=1386699096.478032517 30 ctime=1386699096.478032517 edfbrowser_153_source/print_to_edf.cpp0000644000175000001440000010334712251654530021070 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "print_to_edf.h" #if defined(__APPLE__) || defined(__MACH__) || defined(__APPLE_CC__) #define fopeno fopen #else #define fseeko fseeko64 #define ftello ftello64 #define fopeno fopen64 #endif void print_screen_to_edf(UI_Mainwindow *mainwindow) { int i, j, k, p, n=0, records, records_written, signalcomps, duration_factor[MAXFILES], temp=0, edfplus=0, tallen, annotationlist_nr=0, annotations_left=1, add_one_sec=0, annot_smp_per_record=16, type, len; long long duration, smpls_written[MAXSIGNALS], s2, preamble=0LL, smpls_preamble[MAXSIGNALS], taltime=0LL, l_temp, referencetime, annot_difftime=0LL; char path[MAX_PATH_LENGTH], scratchpad[512], datrecduration[8], *viewbuf; double frequency, frequency2, dig_value; FILE *outputfile; struct signalcompblock **signalcomp; union { signed int one_signed; signed short two_signed[2]; unsigned char four[4]; } wr_var; union { signed short one_signed; unsigned char two[2]; } null_bytes[MAXSIGNALS]; struct annotationblock *annotations_pntr; struct date_time_struct date_time; ///////////////////////////////////////////////////////////////////////// signalcomps = mainwindow->signalcomps; signalcomp = mainwindow->signalcomp; viewbuf = mainwindow->viewbuf; annotations_pntr = mainwindow->annotationlist[0]; if((!mainwindow->files_open)||(!signalcomps)) { QMessageBox messagewindow(QMessageBox::Critical, "Print to EDF", "Put a signal on the screen and try again."); messagewindow.exec(); return; } for(i=0; ifiles_open; i++) { if(mainwindow->edfheaderlist[i]->bdf) { QMessageBox messagewindow(QMessageBox::Critical, "Print to EDF", "BDF files can not be printed to EDF."); messagewindow.exec(); return; } if(mainwindow->edfheaderlist[i]->discontinuous) { QMessageBox messagewindow(QMessageBox::Critical, "Print to EDF", "Sorry, discontinues EDF files can not be printed to EDF."); messagewindow.exec(); return; } if(mainwindow->edfheaderlist[i]->edfplus) { edfplus = 1; for(j=0; jedfheaderlist[i]->nr_annot_chns; j++) { if(mainwindow->edfheaderlist[i]->edfparam[mainwindow->edfheaderlist[i]->annot_ch[j]].smp_per_record>annot_smp_per_record) { annot_smp_per_record = mainwindow->edfheaderlist[i]->edfparam[mainwindow->edfheaderlist[i]->annot_ch[j]].smp_per_record; } } } } annot_smp_per_record += 16; taltime = mainwindow->edfheaderlist[mainwindow->sel_viewtime]->starttime_offset; duration = 0; for(i=0; iedfhdr->long_data_record_duration>duration) { duration = signalcomp[i]->edfhdr->long_data_record_duration; n = i; } } fseeko(signalcomp[n]->edfhdr->file_hdl, 244LL, SEEK_SET); if(fread(datrecduration, 8, 1, signalcomp[n]->edfhdr->file_hdl)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while reading from inputfile."); messagewindow.exec(); return; } temp = 0; for(i=0; iedfhdr->long_data_record_duration) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "This combination of files can not be printed to EDF\n" "because the quotient of the datarecordblock durations is not an integer."); messagewindow.exec(); return; } duration_factor[signalcomp[i]->filenum] = duration / signalcomp[i]->edfhdr->long_data_record_duration; temp += signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].smp_per_record; } 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[mainwindow->sel_viewtime]->filename, MAX_PATH_LENGTH - len); remove_extension_from_filename(path); strcat(path, "_screenprint.edf"); strcpy(path, QFileDialog::getSaveFileName(0, "Print to EDF", QString::fromLocal8Bit(path), "EDF files (*.edf *.EDF)").toLocal8Bit().data()); if(!strcmp(path, "")) { return; } get_directory_from_path(mainwindow->recent_savedir, path, MAX_PATH_LENGTH); if(mainwindow->file_is_opened(path)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Error, selected file is in use."); messagewindow.exec(); return; } outputfile = fopeno(path, "wb"); if(outputfile==NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not create a file for writing."); messagewindow.exec(); return; } referencetime = mainwindow->edfheaderlist[mainwindow->sel_viewtime]->utc_starttime; if(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->viewtime<0) { if((-mainwindow->edfheaderlist[mainwindow->sel_viewtime]->viewtime) % TIME_DIMENSION) { preamble = TIME_DIMENSION - ((-mainwindow->edfheaderlist[mainwindow->sel_viewtime]->viewtime) % TIME_DIMENSION); referencetime--; add_one_sec = 1; } } else { preamble = mainwindow->edfheaderlist[mainwindow->sel_viewtime]->viewtime % TIME_DIMENSION; if(preamble) add_one_sec = 1; } for(i=0; iedfhdr->long_data_record_duration / signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].smp_per_record); } referencetime += (mainwindow->edfheaderlist[mainwindow->sel_viewtime]->viewtime / TIME_DIMENSION); utc_to_date_time(referencetime, &date_time); /************************* write EDF-header ***************************************/ rewind(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->file_hdl); rewind(outputfile); if(edfplus) { if(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->edfplus) { if(fread(scratchpad, 88, 1, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->file_hdl)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while reading from inputfile."); messagewindow.exec(); fclose(outputfile); return; } if(fwrite(scratchpad, 88, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } else { fprintf(outputfile, "0 X X X X "); if(fread(scratchpad, 88, 1, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->file_hdl)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while reading from inputfile."); messagewindow.exec(); fclose(outputfile); return; } if(fwrite(scratchpad + 8, 72, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } fprintf(outputfile, "Startdate %02i-", date_time.day); switch(date_time.month) { case 1 : fprintf(outputfile, "JAN"); break; case 2 : fprintf(outputfile, "FEB"); break; case 3 : fprintf(outputfile, "MAR"); break; case 4 : fprintf(outputfile, "APR"); break; case 5 : fprintf(outputfile, "MAY"); break; case 6 : fprintf(outputfile, "JUN"); break; case 7 : fprintf(outputfile, "JUL"); break; case 8 : fprintf(outputfile, "AUG"); break; case 9 : fprintf(outputfile, "SEP"); break; case 10 : fprintf(outputfile, "OCT"); break; case 11 : fprintf(outputfile, "NOV"); break; case 12 : fprintf(outputfile, "DEC"); break; default : fprintf(outputfile, "ERR"); break; } fprintf(outputfile, "-%04i ", date_time.year); if(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->edfplus) { if(fread(scratchpad, 80, 1, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->file_hdl)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while reading from inputfile."); messagewindow.exec(); fclose(outputfile); return; } if(scratchpad[10]=='X') { if(fwrite(scratchpad + 12, 58, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } else { if(fwrite(scratchpad + 22, 58, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } } else { fprintf(outputfile, "X X X "); if(fread(scratchpad, 80, 1, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->file_hdl)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while reading from inputfile."); messagewindow.exec(); fclose(outputfile); return; } if(fwrite(scratchpad + 28, 52, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } } else { if(fread(scratchpad, 168, 1, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->file_hdl)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while reading from inputfile."); messagewindow.exec(); fclose(outputfile); return; } if(fwrite(scratchpad, 168, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } fprintf(outputfile, "%02i.%02i.%02i%02i.%02i.%02i", date_time.day, date_time.month, date_time.year % 100, date_time.hour, date_time.minute, date_time.second); fprintf(outputfile, "%-8i", (signalcomps + edfplus) * 256 + 256); if(edfplus) { fprintf(outputfile, "EDF+C"); for(i=0; i<39; i++) fputc(' ', outputfile); } else for(i=0; i<44; i++) fputc(' ', outputfile); records = (int)(mainwindow->pagetime / duration); if(add_one_sec) { records += TIME_DIMENSION / duration; } fprintf(outputfile, "%-8i", records); if(fwrite(datrecduration, 8, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } fprintf(outputfile, "%-4i", signalcomps + edfplus); for(i=0; isignallabel); strcat(scratchpad, " "); if(fwrite(scratchpad, 16, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } if(edfplus) { if(fwrite("EDF Annotations ", 16, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } for(i=0; iedfhdr->edfparam[signalcomp[i]->edfsignal[0]].transducer, 80, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } if(edfplus) { for(i=0; i<80; i++) fputc(' ', outputfile); } for(i=0; iphysdimension); strcat(scratchpad, " "); if(fwrite(scratchpad, 8, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } if(edfplus) { for(i=0; i<8; i++) fputc(' ', outputfile); } for(i=0; iecg_filter == NULL) && (signalcomp[i]->zratio_filter == NULL)) { fseeko(signalcomp[i]->edfhdr->file_hdl, (long long)((signalcomp[i]->edfsignal[0] * 8) + (104 * signalcomp[i]->edfhdr->edfsignals) + 256), SEEK_SET); if(fread(scratchpad, 8, 1, signalcomp[i]->edfhdr->file_hdl)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while reading from inputfile."); messagewindow.exec(); fclose(outputfile); return; } if(fwrite(scratchpad, 8, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } if(signalcomp[i]->ecg_filter != NULL) { if(fwrite("0 ", 8, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } if(signalcomp[i]->zratio_filter != NULL) { if(fwrite("-1 ", 8, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } } if(edfplus) { if(fwrite("-1 ", 8, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } for(i=0; iecg_filter == NULL) && (signalcomp[i]->zratio_filter == NULL)) { fseeko(signalcomp[i]->edfhdr->file_hdl, (long long)((signalcomp[i]->edfsignal[0] * 8) + (112 * signalcomp[i]->edfhdr->edfsignals) + 256), SEEK_SET); if(fread(scratchpad, 8, 1, signalcomp[i]->edfhdr->file_hdl)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while reading from inputfile."); messagewindow.exec(); fclose(outputfile); return; } if(fwrite(scratchpad, 8, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } if(signalcomp[i]->ecg_filter != NULL) { if(fwrite("1000 ", 8, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } if(signalcomp[i]->zratio_filter != NULL) { if(fwrite("1 ", 8, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } } if(edfplus) { if(fwrite("1 ", 8, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } for(i=0; iecg_filter == NULL) && (signalcomp[i]->zratio_filter == NULL)) { fprintf(outputfile, "%-8i", signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].dig_min); if(signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].dig_min<0) { null_bytes[i].one_signed = 0; } else { null_bytes[i].one_signed = signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].dig_min; } } else { if(fwrite("-32768 ", 8, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } null_bytes[i].one_signed = -32768; } } if(edfplus) { if(fwrite("-32768 ", 8, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } for(i=0; iecg_filter == NULL) && (signalcomp[i]->zratio_filter == NULL)) { fprintf(outputfile, "%-8i", signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].dig_max); } else { if(fwrite("32767 ", 8, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } } if(edfplus) { if(fwrite("32767 ", 8, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } for(i=0; iedfhdr->edfparam[signalcomp[i]->edfsignal[0]].prefilter); strcat(scratchpad, " "); for(p = strlen(scratchpad) - 1; p>=0; p--) { if(scratchpad[p]!=' ') break; } p++; if(p) p++; for(j=0; jfilter_cnt; j++) { if(signalcomp[i]->filter[j]->is_LPF == 1) { p += sprintf(scratchpad + p, "LP:%f", signalcomp[i]->filter[j]->cutoff_frequency); } if(signalcomp[i]->filter[j]->is_LPF == 0) { p += sprintf(scratchpad + p, "HP:%f", signalcomp[i]->filter[j]->cutoff_frequency); } for(k=(p-1); k>0; k--) { if(scratchpad[k]!='0') break; } if(scratchpad[k]=='.') scratchpad[k] = 0; else scratchpad[k+1] = 0; strcat(scratchpad, "Hz "); p = strlen(scratchpad); if(p>80) break; } for(j=0; jfidfilter_cnt; j++) { type = signalcomp[i]->fidfilter_type[j]; frequency = signalcomp[i]->fidfilter_freq[j]; frequency2 = signalcomp[i]->fidfilter_freq2[j]; if(type == 0) { p += sprintf(scratchpad + p, "HP:%f", frequency); } if(type == 1) { p += sprintf(scratchpad + p, "LP:%f", frequency); } if(type == 2) { p += sprintf(scratchpad + p, "N:%f", frequency); } if(type == 3) { p += sprintf(scratchpad + p, "BP:%f", frequency); } if(type == 4) { p += sprintf(scratchpad + p, "BS:%f", frequency); } for(k=(p-1); k>0; k--) { if(scratchpad[k]!='0') break; } if(scratchpad[k]=='.') scratchpad[k] = 0; else scratchpad[k+1] = 0; p = strlen(scratchpad); if((type == 3) || (type == 4)) { p += sprintf(scratchpad + p, "-%f", frequency2); for(k=(p-1); k>0; k--) { if(scratchpad[k]!='0') break; } if(scratchpad[k]=='.') scratchpad[k] = 0; else scratchpad[k+1] = 0; } strcat(scratchpad, "Hz "); p = strlen(scratchpad); if(p>80) break; } for(j=0; jravg_filter_cnt; j++) { if(signalcomp[i]->ravg_filter_type[j] == 0) { p += sprintf(scratchpad + p, "HP:%iSmpls ", signalcomp[i]->ravg_filter[j]->size); } if(signalcomp[i]->ravg_filter_type[j] == 1) { p += sprintf(scratchpad + p, "LP:%iSmpls ", signalcomp[i]->ravg_filter[j]->size); } p = strlen(scratchpad); if(p>80) break; } if(signalcomp[i]->ecg_filter != NULL) { p += sprintf(scratchpad + p, "ECG:HR "); } if(signalcomp[i]->zratio_filter != NULL) { p += sprintf(scratchpad + p, "Z-ratio "); } for(;p<81; p++) { scratchpad[p] = ' '; } if(fwrite(scratchpad, 80, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } if(edfplus) { for(i=0; i<80; i++) fputc(' ', outputfile); } for(i=0; iedfhdr->edfparam[signalcomp[i]->edfsignal[0]].smp_per_record * duration_factor[signalcomp[i]->filenum]); } if(edfplus) { fprintf(outputfile, "%-8i", annot_smp_per_record); } for(i=0; iprint_to_edf_active = 1; mainwindow->setup_viewbuf(); viewbuf = mainwindow->viewbuf; if(viewbuf==NULL) { fclose(outputfile); return; } QApplication::setOverrideCursor(Qt::WaitCursor); for(records_written=0; records_writtenprocessEvents(); for(i=0; iedfhdr->edfparam[signalcomp[i]->edfsignal[0]].smp_per_record * duration_factor[signalcomp[i]->filenum]; k++) { if(smpls_preamble[i]) { smpls_preamble[i]--; fputc(null_bytes[i].two[0], outputfile); if(fputc(null_bytes[i].two[1], outputfile)==EOF) { QApplication::restoreOverrideCursor(); QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } else { dig_value = 0; s2 = smpls_written[i] + signalcomp[i]->sample_timeoffset - signalcomp[i]->sample_start; for(j=0; jnum_of_signals; j++) { if((smpls_written[i]sample_stop)&&(s2>=0)) { if(signalcomp[i]->edfhdr->edf) { temp = *(((short *)( viewbuf + signalcomp[i]->viewbufoffset + (signalcomp[i]->edfhdr->recordsize * (s2 / signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[j]].smp_per_record)) + signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[j]].buf_offset)) + (s2 % signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[j]].smp_per_record)); } temp += signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[j]].offset; temp *= signalcomp[i]->factor[j]; temp -= signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[j]].offset; } else { temp = 0; } dig_value += temp; } for(p=0; pfilter_cnt; p++) { if(smpls_written[i]==signalcomp[i]->sample_start) { if(mainwindow->edfheaderlist[signalcomp[i]->filenum]->viewtime==0) { reset_filter(dig_value, signalcomp[i]->filter[p]); } else { signalcomp[i]->filter[p]->old_input = signalcomp[i]->filterpreset_a[p]; signalcomp[i]->filter[p]->old_output = signalcomp[i]->filterpreset_b[p]; } } dig_value = first_order_filter(dig_value, signalcomp[i]->filter[p]); } for(p=0; pravg_filter_cnt; p++) { if(smpls_written[i]==signalcomp[i]->sample_start) { if(mainwindow->edfheaderlist[signalcomp[i]->filenum]->viewtime!=0) { ravg_filter_restore_buf(signalcomp[i]->ravg_filter[p]); } } dig_value = run_ravg_filter(dig_value, signalcomp[i]->ravg_filter[p]); } for(p=0; pfidfilter_cnt; p++) { if(smpls_written[i]==signalcomp[i]->sample_start) { if(mainwindow->edfheaderlist[signalcomp[i]->filenum]->viewtime!=0) { memcpy(signalcomp[i]->fidbuf[p], signalcomp[i]->fidbuf2[p], fid_run_bufsize(signalcomp[i]->fid_run[p])); } } dig_value = signalcomp[i]->fidfuncp[p](signalcomp[i]->fidbuf[p], dig_value); } if(signalcomp[i]->ecg_filter != NULL) { if(smpls_written[i]==signalcomp[i]->sample_start) { if(mainwindow->edfheaderlist[signalcomp[i]->filenum]->viewtime != 0) { ecg_filter_restore_buf(signalcomp[i]->ecg_filter); } } dig_value = run_ecg_filter(dig_value, signalcomp[i]->ecg_filter); dig_value = (dig_value * signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].bitvalue * 65.536) - 32768.0; } if(signalcomp[i]->zratio_filter != NULL) { if(smpls_written[i]==signalcomp[i]->sample_start) { if(mainwindow->edfheaderlist[signalcomp[i]->filenum]->viewtime != 0) { zratio_filter_restore_buf(signalcomp[i]->zratio_filter); } } dig_value = run_zratio_filter(dig_value, signalcomp[i]->zratio_filter); dig_value = dig_value * signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].bitvalue * 32768.0; } if((smpls_written[i]>=signalcomp[i]->sample_start)&&(smpls_written[i]sample_stop)) { wr_var.one_signed = dig_value; if((signalcomp[i]->ecg_filter == NULL) && (signalcomp[i]->zratio_filter == NULL)) { if(wr_var.one_signed>signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].dig_max) { wr_var.one_signed = signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].dig_max; } if(wr_var.one_signededfhdr->edfparam[signalcomp[i]->edfsignal[0]].dig_min) { wr_var.one_signed = signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].dig_min; } } else { if(wr_var.one_signed > 32767) { wr_var.one_signed = 32767; } if(wr_var.one_signed < -32768) { wr_var.one_signed = -32768; } } fputc(wr_var.four[0], outputfile); if(fputc(wr_var.four[1], outputfile)==EOF) { QApplication::restoreOverrideCursor(); QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } else { fputc(null_bytes[i].two[0], outputfile); if(fputc(null_bytes[i].two[1], outputfile)==EOF) { QApplication::restoreOverrideCursor(); QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } smpls_written[i]++; } } } if(edfplus) { tallen = fprintf(outputfile, "+%i.%07i", (int)(taltime / TIME_DIMENSION), (int)(taltime % TIME_DIMENSION)); fputc(20, outputfile); fputc(20, outputfile); fputc(0, outputfile); tallen += 3; if(annotations_left) { if(mainwindow->viewtime_sync==VIEWTIME_SYNCED_ABSOLUT) { annot_difftime = (referencetime - mainwindow->edfheaderlist[annotationlist_nr]->utc_starttime) * TIME_DIMENSION; } if(mainwindow->viewtime_sync==VIEWTIME_SYNCED_OFFSET) { annot_difftime = (referencetime - mainwindow->edfheaderlist[mainwindow->sel_viewtime]->utc_starttime) * TIME_DIMENSION; } if((mainwindow->viewtime_sync==VIEWTIME_UNSYNCED) || (mainwindow->viewtime_sync==VIEWTIME_USER_DEF_SYNCED)) { annot_difftime = (referencetime - mainwindow->edfheaderlist[mainwindow->sel_viewtime]->utc_starttime) * TIME_DIMENSION; annot_difftime += (mainwindow->edfheaderlist[annotationlist_nr]->viewtime - mainwindow->edfheaderlist[mainwindow->sel_viewtime]->viewtime); } if(annotationlist_nr != mainwindow->sel_viewtime) { annot_difftime -= mainwindow->edfheaderlist[mainwindow->sel_viewtime]->starttime_offset; annot_difftime += mainwindow->edfheaderlist[annotationlist_nr]->starttime_offset; } } while(annotations_left) { while(!annotations_pntr) { annotationlist_nr++; if(annotationlist_nr>=mainwindow->files_open) { annotations_left = 0; annotations_pntr = NULL; break; } annotations_pntr = mainwindow->annotationlist[annotationlist_nr]; if(mainwindow->viewtime_sync==VIEWTIME_SYNCED_ABSOLUT) { annot_difftime = (referencetime - mainwindow->edfheaderlist[annotationlist_nr]->utc_starttime) * TIME_DIMENSION; } if(mainwindow->viewtime_sync==VIEWTIME_SYNCED_OFFSET) { annot_difftime = (referencetime - mainwindow->edfheaderlist[mainwindow->sel_viewtime]->utc_starttime) * TIME_DIMENSION; } if((mainwindow->viewtime_sync==VIEWTIME_UNSYNCED) || (mainwindow->viewtime_sync==VIEWTIME_USER_DEF_SYNCED)) { annot_difftime = (referencetime - mainwindow->edfheaderlist[mainwindow->sel_viewtime]->utc_starttime) * TIME_DIMENSION; annot_difftime += (mainwindow->edfheaderlist[annotationlist_nr]->viewtime - mainwindow->edfheaderlist[mainwindow->sel_viewtime]->viewtime); } if(annotationlist_nr != mainwindow->sel_viewtime) { annot_difftime -= mainwindow->edfheaderlist[mainwindow->sel_viewtime]->starttime_offset; annot_difftime += mainwindow->edfheaderlist[annotationlist_nr]->starttime_offset; } } if(!annotations_left) break; if(annotations_pntr) { l_temp = annotations_pntr->onset - annot_difftime; if((l_temp >= 0LL) && (l_temp < (mainwindow->pagetime + TIME_DIMENSION))) { tallen += fprintf(outputfile, "%+i.%07i", (int)(l_temp / TIME_DIMENSION), (int)(l_temp % TIME_DIMENSION)); if(annotations_pntr->duration[0]!=0) { fputc(21, outputfile); tallen++; tallen += fprintf(outputfile, "%s", annotations_pntr->duration); } fputc(20, outputfile); tallen++; tallen += fprintf(outputfile, "%s", annotations_pntr->annotation); fputc(20, outputfile); fputc(0, outputfile); tallen += 2; annotations_pntr = annotations_pntr->next_annotation; break; } else { annotations_pntr = annotations_pntr->next_annotation; continue; } } } for(j=tallen; j<(annot_smp_per_record * 2); j++) { fputc(0, outputfile); } taltime += duration; } } QApplication::restoreOverrideCursor(); fclose(outputfile); } edfbrowser_153_source/PaxHeaders.2978/signal_chooser.cpp0000644000175000001440000000013212251654530021652 xustar000000000000000030 mtime=1386699096.479032511 30 atime=1386699096.479032511 30 ctime=1386699096.479032511 edfbrowser_153_source/signal_chooser.cpp0000644000175000001440000002561112251654530021410 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "signal_chooser.h" UI_SignalChooser::UI_SignalChooser(QWidget *w_parent, int job, int *sgnl_nr) { task = job; signal_nr = sgnl_nr; mainwindow = (UI_Mainwindow *)w_parent; signalchooser_dialog = new QDialog(w_parent); if(task == 3) { signalchooser_dialog->setMinimumSize(QSize(265, 400)); signalchooser_dialog->setMaximumSize(QSize(265, 400)); signalchooser_dialog->setWindowTitle("Organize signals"); } else { signalchooser_dialog->setMinimumSize(QSize(200, 400)); signalchooser_dialog->setMaximumSize(QSize(200, 400)); signalchooser_dialog->setWindowTitle("Signals"); } signalchooser_dialog->setModal(TRUE); signalchooser_dialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); list = new QListWidget(signalchooser_dialog); list->setGeometry(5, 5, 130, 365); list->setSelectionBehavior(QAbstractItemView::SelectRows); if(task == 3) { list->setSelectionMode(QAbstractItemView::ExtendedSelection); } else { list->setSelectionMode(QAbstractItemView::SingleSelection); } CloseButton = new QPushButton(signalchooser_dialog); CloseButton->setGeometry(5, 375, 130, 20); CloseButton->setText("Close"); if(task == 3) { UpButton = new QPushButton(signalchooser_dialog); UpButton->setGeometry(150, 180, 100, 20); UpButton->setText("Up"); DownButton = new QPushButton(signalchooser_dialog); DownButton->setGeometry(150, 220, 100, 20); DownButton->setText("Down"); InvertButton = new QPushButton(signalchooser_dialog); InvertButton->setGeometry(150, 260, 100, 20); InvertButton->setText("Invert"); DeleteButton = new QPushButton(signalchooser_dialog); DeleteButton->setGeometry(150, 300, 100, 20); DeleteButton->setText("Remove"); } load_signalcomps(); QObject::connect(CloseButton, SIGNAL(clicked()), signalchooser_dialog, SLOT(close())); if(task == 3) { if(list->count() > 0) { list->setCurrentRow(0); QObject::connect(UpButton, SIGNAL(clicked()), this, SLOT(signalUp())); QObject::connect(DownButton, SIGNAL(clicked()), this, SLOT(signalDown())); QObject::connect(InvertButton, SIGNAL(clicked()), this, SLOT(signalInvert())); QObject::connect(DeleteButton, SIGNAL(clicked()), this, SLOT(signalDelete())); } } else { QObject::connect(list, SIGNAL(itemClicked(QListWidgetItem *)), this, SLOT(call_sidemenu(QListWidgetItem *))); } signalchooser_dialog->exec(); } void UI_SignalChooser::load_signalcomps(void) { int i; QListWidgetItem *item; list->clear(); for(i=0; isignalcomps; i++) { item = new QListWidgetItem; item->setText(mainwindow->signalcomp[i]->signallabel); item->setData(Qt::UserRole, QVariant(i)); list->addItem(item); } } void UI_SignalChooser::call_sidemenu(QListWidgetItem *) { if(task == 3) return; signalchooser_dialog->hide(); if(task == 0) { mainwindow->maincurve->exec_sidemenu(list->currentRow()); } if(task == 1) { mainwindow->spectrumdock->init(list->currentRow()); } if(task == 2) { AdjustFilterSettings filtersettings(mainwindow->signalcomp[list->currentRow()], mainwindow->maincurve); } if(task == 4) { if(signal_nr != NULL) { *signal_nr = list->currentRow(); } } signalchooser_dialog->close(); } void UI_SignalChooser::signalUp() { int i, n, size, sigcomp_nr, selected_signals[MAXSIGNALS]; QList selectedlist; struct signalcompblock *signalcomp; selectedlist = list->selectedItems(); n = selectedlist.size(); if(n < 1) { return; } size = list->count(); if(size < (n + 1)) { return; } if(selectedlist.at(0)->data(Qt::UserRole).toInt() < 1) { return; } for(i=0; idata(Qt::UserRole).toInt(); signalcomp = mainwindow->signalcomp[sigcomp_nr]; mainwindow->signalcomp[sigcomp_nr] = mainwindow->signalcomp[sigcomp_nr - 1]; mainwindow->signalcomp[sigcomp_nr - 1] = signalcomp; selected_signals[i] = sigcomp_nr; } load_signalcomps(); for(i=0; iitem(selected_signals[i] - 1)->setSelected(TRUE); } mainwindow->setup_viewbuf(); } void UI_SignalChooser::signalDown() { int i, n, size, sigcomp_nr, selected_signals[MAXSIGNALS]; QList selectedlist; struct signalcompblock *signalcomp; selectedlist = list->selectedItems(); n = selectedlist.size(); if(n < 1) { return; } size = list->count(); if(size < (n + 1)) { return; } if(selectedlist.at(n - 1)->data(Qt::UserRole).toInt() > (size - 2)) { return; } for(i=(n-1); i>=0; i--) { sigcomp_nr = selectedlist.at(i)->data(Qt::UserRole).toInt(); signalcomp = mainwindow->signalcomp[sigcomp_nr]; mainwindow->signalcomp[sigcomp_nr] = mainwindow->signalcomp[sigcomp_nr + 1]; mainwindow->signalcomp[sigcomp_nr + 1] = signalcomp; selected_signals[i] = sigcomp_nr; } load_signalcomps(); for(i=0; iitem(selected_signals[i] + 1)->setSelected(TRUE); } mainwindow->setup_viewbuf(); } void UI_SignalChooser::signalDelete() { int i, j, k, n, p, sigcomp_nr; QListWidgetItem *item; QList selectedlist; selectedlist = list->selectedItems(); n = selectedlist.size(); if(n < 1) { return; } for(k=0; kdata(Qt::UserRole).toInt(); sigcomp_nr -= k; if(mainwindow->spectrumdock->signalcomp == mainwindow->signalcomp[sigcomp_nr]) { mainwindow->spectrumdock->clear(); mainwindow->spectrumdock->dock->hide(); } for(i=0; isignalcomp[sigcomp_nr]->spectr_dialog[i]; if(p != 0) { delete mainwindow->spectrumdialog[p - 1]; mainwindow->spectrumdialog[p - 1] = NULL; } } for(i=0; isignalcomp[sigcomp_nr]->avg_dialog[i]; if(p != 0) { delete mainwindow->averagecurvedialog[p - 1]; mainwindow->averagecurvedialog[p - 1] = NULL; } } if(mainwindow->signalcomp[sigcomp_nr]->hascursor2) { mainwindow->maincurve->crosshair_2.active = 0; mainwindow->maincurve->crosshair_2.moving = 0; } if(mainwindow->signalcomp[sigcomp_nr]->hascursor1) { mainwindow->maincurve->crosshair_1.active = 0; mainwindow->maincurve->crosshair_2.active = 0; mainwindow->maincurve->crosshair_1.moving = 0; mainwindow->maincurve->crosshair_2.moving = 0; for(i=0; isignalcomps; i++) { mainwindow->signalcomp[i]->hascursor2 = 0; } } if(mainwindow->signalcomp[sigcomp_nr]->hasruler) { mainwindow->maincurve->ruler_active = 0; mainwindow->maincurve->ruler_moving = 0; } for(j=0; jsignalcomp[sigcomp_nr]->filter_cnt; j++) { free(mainwindow->signalcomp[sigcomp_nr]->filter[j]); } mainwindow->signalcomp[sigcomp_nr]->filter_cnt = 0; for(j=0; jsignalcomp[sigcomp_nr]->ravg_filter_cnt; j++) { free_ravg_filter(mainwindow->signalcomp[sigcomp_nr]->ravg_filter[j]); } mainwindow->signalcomp[sigcomp_nr]->ravg_filter_cnt = 0; if(mainwindow->signalcomp[sigcomp_nr]->ecg_filter != NULL) { free_ecg_filter(mainwindow->signalcomp[sigcomp_nr]->ecg_filter); mainwindow->signalcomp[sigcomp_nr]->ecg_filter = NULL; strcpy(mainwindow->signalcomp[sigcomp_nr]->signallabel, mainwindow->signalcomp[sigcomp_nr]->signallabel_bu); mainwindow->signalcomp[sigcomp_nr]->signallabellen = mainwindow->signalcomp[sigcomp_nr]->signallabellen_bu; strcpy(mainwindow->signalcomp[sigcomp_nr]->physdimension, mainwindow->signalcomp[sigcomp_nr]->physdimension_bu); } for(j=0; jsignalcomp[sigcomp_nr]->fidfilter_cnt; j++) { free(mainwindow->signalcomp[sigcomp_nr]->fidfilter[j]); fid_run_free(mainwindow->signalcomp[sigcomp_nr]->fid_run[j]); fid_run_freebuf(mainwindow->signalcomp[sigcomp_nr]->fidbuf[j]); fid_run_freebuf(mainwindow->signalcomp[sigcomp_nr]->fidbuf2[j]); } mainwindow->signalcomp[sigcomp_nr]->fidfilter_cnt = 0; free(mainwindow->signalcomp[sigcomp_nr]); for(i=sigcomp_nr; isignalcomps - 1; i++) { mainwindow->signalcomp[i] = mainwindow->signalcomp[i + 1]; } mainwindow->signalcomps--; } load_signalcomps(); mainwindow->setup_viewbuf(); } void UI_SignalChooser::signalInvert() { int i, j, k, n, selected_signals[MAXSIGNALS]; QList selectedlist; selectedlist = list->selectedItems(); n = selectedlist.size(); if(n < 1) { return; } for(k=0; kdata(Qt::UserRole).toInt(); selected_signals[k] = j; if(mainwindow->signalcomp[j]->polarity != 1) { mainwindow->signalcomp[j]->polarity = 1; } else { mainwindow->signalcomp[j]->polarity = -1; } } load_signalcomps(); for(i=0; iitem(selected_signals[i])->setSelected(TRUE); } mainwindow->setup_viewbuf(); } void UI_SignalChooser::strip_types_from_label(char *label) { int i, len; len = strlen(label); if(len<16) { return; } if((!(strncmp(label, "EEG ", 4))) ||(!(strncmp(label, "ECG ", 4))) ||(!(strncmp(label, "EOG ", 4))) ||(!(strncmp(label, "ERG ", 4))) ||(!(strncmp(label, "EMG ", 4))) ||(!(strncmp(label, "MEG ", 4))) ||(!(strncmp(label, "MCG ", 4)))) { if(label[4]!=' ') { for(i=0; i<(len-4); i++) { label[i] = label[i+4]; } for(; isetMinimumSize(QSize(800, 180)); EDFCompatDialog->setMaximumSize(QSize(800, 180)); EDFCompatDialog->setWindowTitle("Check EDF(+) / BDF(+) compatibility"); EDFCompatDialog->setModal(TRUE); EDFCompatDialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); filelist = new QListWidget(EDFCompatDialog); filelist->setGeometry(QRect(10, 10, 780, 75)); filelist->setSelectionBehavior(QAbstractItemView::SelectRows); filelist->setSelectionMode(QAbstractItemView::SingleSelection); for(i=0; ifiles_open; i++) { if((mainwindow->edfheaderlist[i]->edf)||(mainwindow->edfheaderlist[i]->bdf)) { new QListWidgetItem(QString::fromLocal8Bit(mainwindow->edfheaderlist[i]->filename), filelist); } } CheckButton = new QPushButton(EDFCompatDialog); CheckButton->setGeometry(QRect(10, 140, 100, 25)); CheckButton->setText("Check"); CloseButton = new QPushButton(EDFCompatDialog); CloseButton->setGeometry(QRect(690, 140, 100, 25)); CloseButton->setText("Close"); QObject::connect(CloseButton, SIGNAL(clicked()), EDFCompatDialog, SLOT(close())); QObject::connect(CheckButton, SIGNAL(clicked()), this, SLOT(CheckButtonClicked())); filelist->setCurrentRow(mainwindow->files_open - 1); EDFCompatDialog->exec(); } void UI_EDFCompatwindow::CheckButtonClicked() { int i, j, k, p, r=0, n, len, edfsignals, datarecords, recordsize, edfplus, discontinuous, bdf, bdfplus, *annot_ch, nr_annot_chns, max, onset, duration, duration_start, zero, max_tal_ln, error, temp, samplesize, annots_in_tal, progress_steps; char *scratchpad, *cnv_buf, txt_string[2048]; double data_record_duration, elapsedtime, time_tmp=0.0; union { unsigned int one; signed int one_signed; unsigned short two[2]; signed short two_signed[2]; unsigned char four[4]; } var; FILE *inputfile; struct edfparamblock *edfparam; if(!mainwindow->files_open) { EDFCompatDialog->close(); return; } CheckButton->setEnabled(FALSE); CloseButton->setEnabled(FALSE); for(i=0; ifiles_open; i++) { if(!strcmp(mainwindow->edfheaderlist[i]->filename, filelist->item(filelist->currentRow())->text().toLocal8Bit().data())) { break; } } if(i==mainwindow->files_open) return; n = i; inputfile = mainwindow->edfheaderlist[n]->file_hdl; edfsignals = mainwindow->edfheaderlist[n]->edfsignals; recordsize = mainwindow->edfheaderlist[n]->recordsize; edfparam = mainwindow->edfheaderlist[n]->edfparam; nr_annot_chns = mainwindow->edfheaderlist[n]->nr_annot_chns; datarecords = mainwindow->edfheaderlist[n]->datarecords; data_record_duration = mainwindow->edfheaderlist[n]->data_record_duration; edfplus = mainwindow->edfheaderlist[n]->edfplus; bdfplus = mainwindow->edfheaderlist[n]->bdfplus; discontinuous = mainwindow->edfheaderlist[n]->discontinuous; annot_ch = mainwindow->edfheaderlist[n]->annot_ch; bdf = mainwindow->edfheaderlist[n]->bdf; if(bdf) samplesize = 3; else samplesize = 2; cnv_buf = (char *)calloc(1, recordsize); if(cnv_buf==NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Malloc error. (cnv_buf)."); messagewindow.exec(); EDFCompatDialog->close(); return; } max_tal_ln = 0; for(i=0; iclose(); return; } if(fseeko(inputfile, (long long)((edfsignals + 1) * 256), SEEK_SET)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while reading inputfile."); messagewindow.exec(); free(cnv_buf); free(scratchpad); EDFCompatDialog->close(); return; } /***************** check the maximum and minimum of samples of all signals ******************************/ QProgressDialog progress("Checking...", "Abort", 0, datarecords, EDFCompatDialog); progress.setWindowModality(Qt::WindowModal); progress.setMinimumDuration(200); progress_steps = datarecords / 100; if(progress_steps < 1) { progress_steps = 1; } elapsedtime = 0.0; for(i=0; iprocessEvents(); if(progress.wasCanceled() == TRUE) { free(cnv_buf); free(scratchpad); EDFCompatDialog->close(); return; } } if(fread(cnv_buf, recordsize, 1, inputfile)!=1) { snprintf(txt_string, 2048, "An error occurred while reading inputfile at datarecord %i.", i + 1); QMessageBox messagewindow(QMessageBox::Critical, "Error", txt_string); messagewindow.exec(); free(cnv_buf); free(scratchpad); EDFCompatDialog->close(); return; } for(j=0; j edfparam[j].dig_max) { snprintf(txt_string, 2048, "Error.\n\nIn datarecord %i -> signal %i -> sample %i is more than digital maximum.\n" "Digital maximum for this signal as written in header is %i but sample is %i.\n" "Offset from start of file: 0x%X\n", i + 1, j + 1, k + 1, edfparam[j].dig_max, temp, (i * recordsize) + edfparam[j].buf_offset + (k * samplesize) + (edfsignals * 256) + 256); progress.reset(); QMessageBox messagewindow(QMessageBox::Critical, "Error", txt_string); messagewindow.exec(); free(scratchpad); free(cnv_buf); EDFCompatDialog->close(); return; } if(temp < edfparam[j].dig_min) { snprintf(txt_string, 2048, "Error.\n\nIn datarecord %i -> signal %i -> sample %i is less than digital minimum.\n" "Digital minimum for this signal as written in header is %i but sample is %i.\n" "Offset from start of file: 0x%X\n", i + 1, j + 1, k + 1, edfparam[j].dig_min, temp, (i * recordsize) + edfparam[j].buf_offset + (k * samplesize) + (edfsignals * 256) + 256); progress.reset(); QMessageBox messagewindow(QMessageBox::Critical, "Error", txt_string); messagewindow.exec(); free(cnv_buf); free(scratchpad); EDFCompatDialog->close(); return; } } } /************** process annotationsignals (if any) **************/ error = 0; for(r=0; r(data_record_duration+0.00000001))||((time_tmp-elapsedtime)<(data_record_duration-0.00000001))) { error = 3; goto END; } } } else { if(time_tmp>=1.0) { error = 2; goto END; } } elapsedtime = time_tmp; error = 0; break; } } } } for(k=0; k1) { 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)) { annots_in_tal++; n = 0; continue; } if(!onset) { scratchpad[n] = 0; if(is_onset_number(scratchpad)) { error = 36; goto END; } onset = 1; n = 0; continue; } if(duration_start) { scratchpad[n] = 0; if(is_duration_number(scratchpad)) { error = 37; goto END; } duration = 1; duration_start = 0; n = 0; continue; } } n++; } END: /****************** end ************************/ if(error) { if(error==1) { snprintf(txt_string, 1700, "Error.\n\nInvalid annotation in datarecord %i.\n", i + 1); } if(error==2) { snprintf(txt_string, 1700, "Error.\n\n" "Time keeping annotation in the first datarecord is %.12f\n" "expected <1.0\n", time_tmp); } if(error==3) { snprintf(txt_string, 1700, "Error.\n\n" "Datarecord duration is %.12f but timestep between\n" "datarecord %i and preceding datarecord is %.12f.\n", data_record_duration, i + 1, time_tmp - elapsedtime); } if(error==4) { snprintf(txt_string, 1700, "Error.\n\nDatarecords are not in chronological order,\n" "datarecord %i has timestamp %.12f and datarecord %i has timestamp %.12f.\n", i, elapsedtime, i + 1, time_tmp); } if(error==5) { snprintf(txt_string, 1700, "Error.\n\nInvalid annotation in datarecord %i,\n" "last byte is not a null-byte.\n", i + 1); } if(error==6) { snprintf(txt_string, 1700, "Error.\n\nInvalid annotation in datarecord %i,\n" "timekeeping TAL (the first annotation in the first annotations signal)\n" "should have two consecutive bytes with values 0x14 immediately after\n" "the number.\n", i + 1); } if(error==33) { snprintf(txt_string, 1700, "Error.\n\nInvalid annotation in datarecord %i,\n" "byte before the first null-byte should be equal to 0x14.\n", i + 1); } if(error==34) { snprintf(txt_string, 1700, "Error.\n\nInvalid annotation in datarecord %i,\n" "after two consecutive null-bytes all of the remaining bytes should be null-bytes as well.\n" "(it's not allowed to have two or more null-bytes between two TAL's)\n", i + 1); } if(error==35) { snprintf(txt_string, 1700, "Error.\n\nInvalid annotation in datarecord %i,\n" "it's not allowed to have multiple duration fields in one TAL or\n" "to have a duration field which is not immediately behind the onsetfield.\n", i + 1); } if(error==36) { snprintf(txt_string, 1700, "Error.\n\nInvalid annotation in datarecord %i,\n" "onset has an invalid number.\n", i + 1); } if(error==37) { snprintf(txt_string, 1700, "Error.\n\nInvalid annotation in datarecord %i,\n" "duration has an invalid number.\n", i + 1); } len = strlen(txt_string); p = (i * recordsize) + (edfsignals * 256) + 256 + (edfparam[annot_ch[r]].buf_offset); snprintf(txt_string + len, 348, "Offset from start of file: 0x%X\n\n" "Stopped at the first error, additional errors may be present.", p); progress.reset(); QMessageBox messagewindow(QMessageBox::Critical, "Error", txt_string); messagewindow.exec(); free(cnv_buf); free(scratchpad); EDFCompatDialog->close(); return; } } } progress.reset(); if(bdf) { if(bdfplus) { QMessageBox messagewindow(QMessageBox::Information, "Result", "No errors found, file is BDF+ compliant."); messagewindow.setIconPixmap(QPixmap(":/images/ok.png")); messagewindow.exec(); } else { QMessageBox messagewindow(QMessageBox::Information, "Result", "No errors found, file is BDF compliant."); messagewindow.setIconPixmap(QPixmap(":/images/ok.png")); messagewindow.exec(); } } else { if(edfplus) { QMessageBox messagewindow(QMessageBox::Information, "Result", "No errors found, file is EDF+ compliant."); messagewindow.setIconPixmap(QPixmap(":/images/ok.png")); messagewindow.exec(); } else { QMessageBox messagewindow(QMessageBox::Information, "Result", "No errors found, file is EDF compliant."); messagewindow.setIconPixmap(QPixmap(":/images/ok.png")); messagewindow.exec(); } } free(cnv_buf); free(scratchpad); EDFCompatDialog->close(); } int UI_EDFCompatwindow::is_duration_number(char *str) { int i, l, hasdot = 0; l = strlen(str); if(!l) return(1); if((str[0] == '.')||(str[l-1] == '.')) return(1); for(i=0; i57)) return(1); } } return(0); } int UI_EDFCompatwindow::is_onset_number(char *str) { int i, l, hasdot = 0; l = strlen(str); if(l<2) return(1); if((str[0]!='+')&&(str[0]!='-')) return(1); if((str[1] == '.')||(str[l-1] == '.')) return(1); for(i=1; i57)) return(1); } } return(0); } int UI_EDFCompatwindow::is_integer_number(char *str) { int i=0, l, hasspace = 0, hassign=0, digit=0; l = strlen(str); if(!l) return(1); if((str[0]=='+')||(str[0]=='-')) { hassign++; i++; } for(; i57)) { return(1); } else { if(hasspace) { return(1); } digit++; } } } if(digit) return(0); else return(1); } int UI_EDFCompatwindow::is_number(char *str) { int i=0, l, hasspace = 0, hassign=0, digit=0, hasdot=0; l = strlen(str); if(!l) return(1); if((str[0]=='+')||(str[0]=='-')) { hassign++; i++; } if(str[l-1]=='.') { return(1); } for(; i57))&&str[i]!='.') { return(1); } else { if(hasspace) { return(1); } if(str[i]=='.') { if(hasdot||!i) return(1); if(hassign&&(i<2)) return(1); hasdot++; } else { digit++; } } } } if(digit) return(0); else return(1); } edfbrowser_153_source/PaxHeaders.2978/active_file_chooser.cpp0000644000175000001440000000013212251654530022647 xustar000000000000000030 mtime=1386699096.476032527 30 atime=1386699096.476032527 30 ctime=1386699096.476032527 edfbrowser_153_source/active_file_chooser.cpp0000644000175000001440000000534212251654530022404 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "active_file_chooser.h" UI_activeFileChooserWindow::UI_activeFileChooserWindow(int *file_nr, QWidget *mainwndw) { int i; mainwindow = (UI_Mainwindow *)mainwndw; file_num = file_nr; *file_num = -1; chooserDialog = new QDialog; chooserDialog->setMinimumSize(QSize(800, 200)); chooserDialog->setMaximumSize(QSize(800, 200)); chooserDialog->setWindowTitle("Choose file"); chooserDialog->setModal(TRUE); chooserDialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); filelist = new QListWidget(chooserDialog); filelist->setGeometry(QRect(10, 10, 780, 110)); filelist->setSelectionBehavior(QAbstractItemView::SelectRows); filelist->setSelectionMode(QAbstractItemView::SingleSelection); for(i=0; ifiles_open; i++) { new QListWidgetItem(QString::fromLocal8Bit(mainwindow->edfheaderlist[i]->filename), filelist); } okButton = new QPushButton(chooserDialog); okButton->setGeometry(10, 140, 100, 25); okButton->setText("OK"); cancelButton = new QPushButton(chooserDialog); cancelButton->setGeometry(690, 140, 100, 25); cancelButton->setText("Cancel"); QObject::connect(cancelButton, SIGNAL(clicked()), chooserDialog, SLOT(close())); QObject::connect(okButton, SIGNAL(clicked()), this, SLOT(okButtonClicked())); filelist->setCurrentRow(mainwindow->files_open - 1); chooserDialog->exec(); } void UI_activeFileChooserWindow::okButtonClicked() { if(!mainwindow->files_open) { *file_num = -1; chooserDialog->close(); return; } *file_num = filelist->currentRow(); chooserDialog->close(); } edfbrowser_153_source/PaxHeaders.2978/images.qrc0000644000175000001440000000013212251654530020123 xustar000000000000000030 mtime=1386699096.491032448 30 atime=1386699096.491032448 30 ctime=1386699096.491032448 edfbrowser_153_source/images.qrc0000644000175000001440000000024412251654530017654 0ustar00novarausers00000000000000 images/edf.png images/splash.png images/ok.png edfbrowser_153_source/PaxHeaders.2978/edf_annot_list.c0000644000175000001440000000013212251654530021303 xustar000000000000000030 mtime=1386699096.471032554 30 atime=1386699096.471032554 30 ctime=1386699096.471032554 edfbrowser_153_source/edf_annot_list.c0000644000175000001440000002140212251654530021033 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "edf_annot_list.h" void edfplus_annotation_add_item(struct annotationblock **list, struct annotationblock *annotation) { struct annotationblock *annotlist; annotlist = *list; annotation->next_annotation = NULL; if(annotlist == NULL) { annotation->former_annotation = NULL; *list = annotation; return; } while(annotlist->next_annotation != NULL) { if(annotlist->next_annotation->onset > annotation->onset) { break; } annotlist = annotlist->next_annotation; } annotation->next_annotation = annotlist->next_annotation; if(annotation->next_annotation != NULL) { annotation->next_annotation->former_annotation = annotation; } annotlist->next_annotation = annotation; annotation->former_annotation = annotlist; } void edfplus_annotation_add_copy(struct annotationblock **list, struct annotationblock *annotation) { struct annotationblock *annotlist, *new_annot; annotlist = *list; new_annot = (struct annotationblock *)calloc(1, sizeof(struct annotationblock)); if(new_annot == NULL) { return; } memcpy(new_annot, annotation, sizeof(struct annotationblock)); new_annot->next_annotation = NULL; if(annotlist == NULL) { new_annot->former_annotation = NULL; *list = new_annot; return; } while(annotlist->next_annotation != NULL) { annotlist = annotlist->next_annotation; } annotlist->next_annotation = new_annot; new_annot->former_annotation = annotlist; } int edfplus_annotation_count(struct annotationblock **list) { int n=0; struct annotationblock *annotlist; annotlist = *list; while(annotlist != NULL) { annotlist = annotlist->next_annotation; n++; } return(n); } void edfplus_annotation_delete(struct annotationblock **list, int n) { struct annotationblock *annotlist; annotlist = *list; if(annotlist==NULL) { return; } while(n) { if(annotlist->next_annotation==NULL) { return; } annotlist = annotlist->next_annotation; n--; } if(annotlist->former_annotation!=NULL) { annotlist->former_annotation->next_annotation = annotlist->next_annotation; } if(annotlist->next_annotation!=NULL) { annotlist->next_annotation->former_annotation = annotlist->former_annotation; } if(annotlist->former_annotation==NULL) { *list = annotlist->next_annotation; } free(annotlist); } void edfplus_annotation_delete_list(struct annotationblock **list) { struct annotationblock *annotlist; annotlist = *list; if(annotlist == NULL) { return; } while(annotlist->next_annotation != NULL) { annotlist = annotlist->next_annotation; free(annotlist->former_annotation); } free(annotlist); *list = NULL; } struct annotationblock * edfplus_annotation_item(struct annotationblock **list, int n) { struct annotationblock *annotlist; annotlist = *list; if(annotlist == NULL) { return(NULL); } while(n) { if(annotlist->next_annotation == NULL) { return(NULL); } annotlist = annotlist->next_annotation; n--; } return(annotlist); } void edfplus_annotation_sort(struct annotationblock **list) // sort the annotationlist based on the onset time { struct annotationblock *p1, *p2, *p3, *pm, *p5; p1 = *list; while(p1 != NULL) { if(p1->next_annotation == NULL) { break; } if(p1->next_annotation->onset < p1->onset) { pm = p1; p2 = p1->next_annotation; // this one we take out p3 = p2->next_annotation; // take out p1->next_annotation = p3; if(p3 != NULL) { p3->former_annotation = p1; } // take out done while(1) // search backwards till we find the right place to put it { p5 = pm->former_annotation; if(p5 == NULL) { pm->former_annotation = p2; p2->next_annotation = pm; p2->former_annotation = NULL; *list = p2; break; } if(p5->onset <= p2->onset) // insert it here { pm->former_annotation = p2; p2->next_annotation = pm; p2->former_annotation = p5; p5->next_annotation = p2; break; } pm = p5; } } else { p1 = p1->next_annotation; // continue searching the list from where we stopped before } } } struct annotationblock * edfplus_annotation_copy_list(struct annotationblock **list) { struct annotationblock *annot, *annot2, *annot3; annot = *list; if(annot==NULL) { return(NULL); } annot2 = (struct annotationblock *)calloc(1, sizeof(struct annotationblock)); annot3 = annot2; memcpy(annot2, annot, sizeof(struct annotationblock)); annot = annot->next_annotation; while(annot!=NULL) { annot2->next_annotation = (struct annotationblock *)calloc(1, sizeof(struct annotationblock)); memcpy(annot2->next_annotation, annot, sizeof(struct annotationblock)); annot2->next_annotation->former_annotation = annot2; annot2 = annot2->next_annotation; annot = annot->next_annotation; } return(annot3); } int get_tal_timestamp_digit_cnt(struct edfhdrblock *hdr) { int timestamp_digits; char scratchpad[256]; long long time; if(hdr==NULL) { return(-1); } time = (hdr->datarecords * hdr->long_data_record_duration) / TIME_DIMENSION; #ifdef _WIN32 timestamp_digits = snprintf(scratchpad, 256, "%I64d", time); #else timestamp_digits = snprintf(scratchpad, 256, "%lli", time); #endif return(timestamp_digits); } int get_tal_timestamp_decimal_cnt(struct edfhdrblock *hdr) { int i, j, timestamp_decimals; if(hdr==NULL) { return(-1); } j = 10; for(timestamp_decimals=7; timestamp_decimals>0; timestamp_decimals--) { if(hdr->long_data_record_duration % j) { break; } j *= 10; } if((hdr->edfplus==1)||(hdr->bdfplus==1)) { j = 10; for(i=7; i>0; i--) { if(hdr->starttime_offset % j) { break; } j *= 10; } if(i > timestamp_decimals) { timestamp_decimals = i; } } return(timestamp_decimals); } int get_max_annotation_strlen(struct annotationblock **list) { int j, len, annot_descr_len=0, annot_duration_len=0, timestamp_digits=0, timestamp_decimals=0; char scratchpad[256]; struct annotationblock *annot; annot = list[0]; if(annot==NULL) { return(0); } while(annot!=NULL) { #ifdef _WIN32 len = snprintf(scratchpad, 256, "%I64d", annot->onset / TIME_DIMENSION); #else len = snprintf(scratchpad, 256, "%lli", annot->onset / TIME_DIMENSION); #endif if(len > timestamp_digits) { timestamp_digits = len; } j = 10; for(len=7; len>0; len--) { if(annot->onset % j) { break; } j *= 10; } if(len > timestamp_decimals) { timestamp_decimals = len; } len = strlen(annot->annotation); if(len>annot_descr_len) { annot_descr_len = len; } len = strlen(annot->duration); if(len>annot_duration_len) { annot_duration_len = len; } annot = annot->next_annotation; } if(annot_duration_len) { annot_duration_len++; } if(timestamp_decimals) { timestamp_decimals++; } // printf("annot_descr_len is %i\n" // "annot_duration_len is %i\n" // "timestamp_digits is %i\n" // "timestamp_decimals is %i\n", // annot_descr_len, // annot_duration_len, // timestamp_digits, // timestamp_decimals); return(annot_descr_len + annot_duration_len + timestamp_digits + timestamp_decimals + 4); } edfbrowser_153_source/PaxHeaders.2978/import_annotations.cpp0000644000175000001440000000013212251654530022602 xustar000000000000000030 mtime=1386699096.478032517 30 atime=1386699096.478032517 30 ctime=1386699096.478032517 edfbrowser_153_source/import_annotations.cpp0000644000175000001440000016077112251654530022347 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "import_annotations.h" #if defined(__APPLE__) || defined(__MACH__) || defined(__APPLE_CC__) #define fopeno fopen #else #define fseeko fseeko64 #define ftello ftello64 #define fopeno fopen64 #endif #define XML_FORMAT 0 #define ASCIICSV_FORMAT 1 #define DCEVENT_FORMAT 2 #define EDFPLUS_FORMAT 3 #define TAB_CNT 4 UI_ImportAnnotationswindow::UI_ImportAnnotationswindow(QWidget *w_parent) { int i; mainwindow = (UI_Mainwindow *)w_parent; if(mainwindow->files_open < 1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not import annotations without opening an EDF/BDF-file first."); messagewindow.exec(); return; } ImportAnnotsDialog = new QDialog; ImportAnnotsDialog->setMinimumSize(490, 500); ImportAnnotsDialog->setMaximumSize(490, 500); ImportAnnotsDialog->setWindowTitle("Import annotations/events"); ImportAnnotsDialog->setModal(TRUE); ImportAnnotsDialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); tabholder = new QTabWidget; tab_index_array[ASCIICSV_FORMAT] = 0; tab_index_array[DCEVENT_FORMAT] = 1; tab_index_array[XML_FORMAT] = 2; tab_index_array[EDFPLUS_FORMAT] = 3; for(i=0; isetText("Column separator"); SeparatorLabel->setMinimumSize(200, 25); OnsetColumnLabel = new QLabel(ImportAnnotsDialog); OnsetColumnLabel->setText("Onset column"); OnsetColumnLabel->setMinimumSize(200, 25); DatastartLabel = new QLabel(ImportAnnotsDialog); DatastartLabel->setText("Data starts at line"); DatastartLabel->setMinimumSize(200, 25); OnsetTimeLabel = new QLabel(ImportAnnotsDialog); OnsetTimeLabel->setText("Onset time coding is"); OnsetTimeLabel->setMinimumSize(200, 25); SeparatorLineEdit = new QLineEdit(ImportAnnotsDialog); SeparatorLineEdit->setMaxLength(3); SeparatorLineEdit->setText("tab"); SeparatorLineEdit->setMinimumSize(80, 25); DescriptionLineEdit = new QLineEdit(ImportAnnotsDialog); DescriptionLineEdit->setMaxLength(20); DescriptionLineEdit->setEnabled(FALSE); DescriptionLineEdit->setMinimumSize(80, 25); OnsetColumnSpinBox = new QSpinBox(ImportAnnotsDialog); OnsetColumnSpinBox->setRange(1,256); OnsetColumnSpinBox->setValue(1); OnsetColumnSpinBox->setMinimumSize(80, 25); DurationColumnSpinBox = new QSpinBox(ImportAnnotsDialog); DurationColumnSpinBox->setRange(1,256); DurationColumnSpinBox->setValue(3); DurationColumnSpinBox->setMinimumSize(80, 25); DescriptionColumnSpinBox = new QSpinBox(ImportAnnotsDialog); DescriptionColumnSpinBox->setRange(1,256); DescriptionColumnSpinBox->setValue(2); DescriptionColumnSpinBox->setMinimumSize(80, 25); DatastartSpinbox = new QSpinBox(ImportAnnotsDialog); DatastartSpinbox->setRange(1,100); DatastartSpinbox->setValue(1); DatastartSpinbox->setMinimumSize(80, 25); RelativeTimeComboBox = new QComboBox(ImportAnnotsDialog); RelativeTimeComboBox->addItem("in seconds, relative to start of file"); RelativeTimeComboBox->addItem("hh:mm:ss"); RelativeTimeComboBox->addItem("hh:mm:ss.xxx"); RelativeTimeComboBox->addItem("yyyy-mm-ddThh:mm:ss"); RelativeTimeComboBox->addItem("yyyy-mm-ddThh:mm:ss.xxx"); RelativeTimeComboBox->setMinimumSize(200, 25); DescriptionColumnRadioButton = new QRadioButton("Description column"); DescriptionColumnRadioButton->setMinimumSize(198, 25); DescriptionColumnRadioButton->setChecked(TRUE); UseManualDescriptionRadioButton = new QRadioButton("Manual description"); UseManualDescriptionRadioButton->setMinimumSize(198, 25); DurationCheckBox = new QCheckBox(" Duration column", ImportAnnotsDialog); DurationCheckBox->setTristate(FALSE); DurationCheckBox->setCheckState(Qt::Unchecked); DurationCheckBox->setMinimumSize(198, 25); asciiSettingsHBoxLayout1 = new QHBoxLayout; asciiSettingsHBoxLayout1->addWidget(SeparatorLabel); asciiSettingsHBoxLayout1->addWidget(SeparatorLineEdit); asciiSettingsHBoxLayout1->addStretch(100); asciiSettingsHBoxLayout2 = new QHBoxLayout; asciiSettingsHBoxLayout2->addWidget(OnsetColumnLabel); asciiSettingsHBoxLayout2->addWidget(OnsetColumnSpinBox); asciiSettingsHBoxLayout2->addStretch(100); asciiSettingsHBoxLayout3 = new QHBoxLayout; asciiSettingsHBoxLayout3->addWidget(DescriptionColumnRadioButton); asciiSettingsHBoxLayout3->addWidget(DescriptionColumnSpinBox); asciiSettingsHBoxLayout3->addStretch(100); asciiSettingsHBoxLayout4 = new QHBoxLayout; asciiSettingsHBoxLayout4->addWidget(UseManualDescriptionRadioButton); asciiSettingsHBoxLayout4->addWidget(DescriptionLineEdit); asciiSettingsHBoxLayout4->addStretch(100); asciiSettingsHBoxLayout7 = new QHBoxLayout; asciiSettingsHBoxLayout7->addWidget(DurationCheckBox); asciiSettingsHBoxLayout7->addWidget(DurationColumnSpinBox); asciiSettingsHBoxLayout7->addStretch(100); asciiSettingsHBoxLayout5 = new QHBoxLayout; asciiSettingsHBoxLayout5->addWidget(DatastartLabel); asciiSettingsHBoxLayout5->addWidget(DatastartSpinbox); asciiSettingsHBoxLayout5->addStretch(100); asciiSettingsHBoxLayout6 = new QHBoxLayout; asciiSettingsHBoxLayout6->addWidget(OnsetTimeLabel); asciiSettingsHBoxLayout6->addWidget(RelativeTimeComboBox); asciiSettingsHBoxLayout6->addStretch(100); asciiSettingsVBoxLayout = new QVBoxLayout; asciiSettingsVBoxLayout->addLayout(asciiSettingsHBoxLayout1); asciiSettingsVBoxLayout->addLayout(asciiSettingsHBoxLayout2); asciiSettingsVBoxLayout->addLayout(asciiSettingsHBoxLayout3); asciiSettingsVBoxLayout->addLayout(asciiSettingsHBoxLayout4); asciiSettingsVBoxLayout->addLayout(asciiSettingsHBoxLayout7); asciiSettingsVBoxLayout->addLayout(asciiSettingsHBoxLayout5); asciiSettingsVBoxLayout->addLayout(asciiSettingsHBoxLayout6); tab[tab_index_array[ASCIICSV_FORMAT]]->setLayout(asciiSettingsVBoxLayout); DCEventSignalLabel = new QLabel(ImportAnnotsDialog); DCEventSignalLabel->setText("Signal"); DCEventSignalLabel->setMinimumSize(130, 25); DCEventBitTimeLabel = new QLabel(ImportAnnotsDialog); DCEventBitTimeLabel->setText("Bit Time"); DCEventBitTimeLabel->setMinimumSize(130, 25); DCEventTriggerLevelLabel = new QLabel(ImportAnnotsDialog); DCEventTriggerLevelLabel->setText("Trigger Level"); DCEventTriggerLevelLabel->setMinimumSize(130, 25); DCEventSignalComboBox = new QComboBox(ImportAnnotsDialog); for(i=0; isignalcomps; i++) { DCEventSignalComboBox->addItem(mainwindow->signalcomp[i]->signallabel); } DCEventSignalComboBox->setMinimumSize(130, 25); BitTimeSpinbox = new QSpinBox(ImportAnnotsDialog); BitTimeSpinbox->setRange(1,1000); BitTimeSpinbox->setSuffix(" mS"); BitTimeSpinbox->setValue(10); BitTimeSpinbox->setMinimumSize(130, 25); DCEventTriggerLevelSpinBox = new QDoubleSpinBox(ImportAnnotsDialog); DCEventTriggerLevelSpinBox->setDecimals(3); DCEventTriggerLevelSpinBox->setRange(-10000.0, 10000.0); DCEventTriggerLevelSpinBox->setValue(500.0); DCEventTriggerLevelSpinBox->setMinimumSize(130, 25); if(mainwindow->signalcomps) { DCEventSignalChanged(0); } DCEventHBoxLayout1 = new QHBoxLayout; DCEventHBoxLayout1->addWidget(DCEventSignalLabel); DCEventHBoxLayout1->addWidget(DCEventSignalComboBox); DCEventHBoxLayout1->addStretch(2); DCEventHBoxLayout2 = new QHBoxLayout; DCEventHBoxLayout2->addWidget(DCEventBitTimeLabel); DCEventHBoxLayout2->addWidget(BitTimeSpinbox); DCEventHBoxLayout2->addStretch(2); DCEventHBoxLayout3 = new QHBoxLayout; DCEventHBoxLayout3->addWidget(DCEventTriggerLevelLabel); DCEventHBoxLayout3->addWidget(DCEventTriggerLevelSpinBox); DCEventHBoxLayout3->addStretch(2); DCEventVBoxLayout = new QVBoxLayout; DCEventVBoxLayout->addStretch(10); DCEventVBoxLayout->addLayout(DCEventHBoxLayout1); DCEventVBoxLayout->addStretch(2); DCEventVBoxLayout->addLayout(DCEventHBoxLayout2); DCEventVBoxLayout->addStretch(2); DCEventVBoxLayout->addLayout(DCEventHBoxLayout3); DCEventVBoxLayout->addStretch(10); tab[tab_index_array[DCEVENT_FORMAT]]->setLayout(DCEventVBoxLayout); tabholder->addTab(tab[tab_index_array[ASCIICSV_FORMAT]], "ASCII / CSV"); tabholder->addTab(tab[tab_index_array[DCEVENT_FORMAT]], "DC-event (8-bit serial code)"); tabholder->addTab(tab[tab_index_array[XML_FORMAT]], "XML"); tabholder->addTab(tab[tab_index_array[EDFPLUS_FORMAT]], "EDF+ / BDF+"); IgnoreConsecutiveCheckBox = new QCheckBox(" Ignore consecutive events with the\n same description"); IgnoreConsecutiveCheckBox->setMinimumSize(300, 40); IgnoreConsecutiveCheckBox->setTristate(FALSE); IgnoreConsecutiveCheckBox->setCheckState(Qt::Unchecked); ImportButton = new QPushButton(ImportAnnotsDialog); ImportButton->setMinimumSize(80, 25); ImportButton->setText("Import"); CloseButton = new QPushButton(ImportAnnotsDialog); CloseButton->setMinimumSize(80, 25); CloseButton->setText("Cancel"); horLayout = new QHBoxLayout; horLayout->addSpacing(30); horLayout->addWidget(ImportButton, 1); horLayout->addSpacing(300); horLayout->addWidget(CloseButton, 1); horLayout->addSpacing(30); mainLayout = new QVBoxLayout; mainLayout->addWidget(tabholder, 300); mainLayout->addSpacing(30); mainLayout->addWidget(IgnoreConsecutiveCheckBox, 30); mainLayout->addSpacing(30); mainLayout->addLayout(horLayout, 30); ImportAnnotsDialog->setLayout(mainLayout); SeparatorLineEdit->setText(mainwindow->import_annotations_var->separator); OnsetColumnSpinBox->setValue(mainwindow->import_annotations_var->onsetcolumn); DescriptionColumnSpinBox->setValue(mainwindow->import_annotations_var->descriptioncolumn); DescriptionLineEdit->setText(mainwindow->import_annotations_var->description); DurationColumnSpinBox->setValue(mainwindow->import_annotations_var->durationcolumn); DatastartSpinbox->setValue(mainwindow->import_annotations_var->datastartline); RelativeTimeComboBox->setCurrentIndex(mainwindow->import_annotations_var->onsettimeformat); BitTimeSpinbox->setValue(mainwindow->import_annotations_var->dceventbittime); DCEventTriggerLevelSpinBox->setValue(mainwindow->import_annotations_var->triggerlevel); if(mainwindow->import_annotations_var->manualdescription == 0) { DescriptionColumnRadioButton->setChecked(TRUE); DescriptionColumnSpinBox->setEnabled(TRUE); DescriptionLineEdit->setEnabled(FALSE); } else { UseManualDescriptionRadioButton->setChecked(TRUE); DescriptionColumnSpinBox->setEnabled(FALSE); DescriptionLineEdit->setEnabled(TRUE); if(mainwindow->import_annotations_var->format == ASCIICSV_FORMAT) { IgnoreConsecutiveCheckBox->setEnabled(FALSE); } } if(mainwindow->import_annotations_var->useduration == 1) { DurationCheckBox->setCheckState(Qt::Checked); DurationColumnSpinBox->setEnabled(TRUE); } else { DurationCheckBox->setCheckState(Qt::Unchecked); DurationColumnSpinBox->setEnabled(FALSE); } if(mainwindow->import_annotations_var->ignoreconsecutive == 1) { IgnoreConsecutiveCheckBox->setCheckState(Qt::Checked); } else { IgnoreConsecutiveCheckBox->setCheckState(Qt::Unchecked); } if(mainwindow->import_annotations_var->format == EDFPLUS_FORMAT) { IgnoreConsecutiveCheckBox->setEnabled(FALSE); } tabholder->setCurrentIndex(tab_index_array[mainwindow->import_annotations_var->format]); QObject::connect(CloseButton, SIGNAL(clicked()), ImportAnnotsDialog, SLOT(close())); QObject::connect(ImportButton, SIGNAL(clicked()), this, SLOT(ImportButtonClicked())); QObject::connect(DCEventSignalComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(DCEventSignalChanged(int))); QObject::connect(DescriptionColumnRadioButton, SIGNAL(toggled(bool)), this, SLOT(descriptionRadioButtonClicked(bool))); QObject::connect(UseManualDescriptionRadioButton, SIGNAL(toggled(bool)), this, SLOT(descriptionRadioButtonClicked(bool))); QObject::connect(DurationCheckBox, SIGNAL(stateChanged(int)), this, SLOT(DurationCheckBoxChanged(int))); QObject::connect(tabholder, SIGNAL(currentChanged(int)), this, SLOT(TabChanged(int))); ImportAnnotsDialog->exec(); } void UI_ImportAnnotationswindow::DurationCheckBoxChanged(int state) { if(state == Qt::Unchecked) { DurationColumnSpinBox->setEnabled(FALSE); } else { DurationColumnSpinBox->setEnabled(TRUE); } } void UI_ImportAnnotationswindow::descriptionRadioButtonClicked(bool) { if(DescriptionColumnRadioButton->isChecked() == TRUE) { DescriptionColumnSpinBox->setEnabled(TRUE); DescriptionLineEdit->setEnabled(FALSE); IgnoreConsecutiveCheckBox->setEnabled(TRUE); } if(UseManualDescriptionRadioButton->isChecked() == TRUE) { DescriptionColumnSpinBox->setEnabled(FALSE); DescriptionLineEdit->setEnabled(TRUE); IgnoreConsecutiveCheckBox->setEnabled(FALSE); } } void UI_ImportAnnotationswindow::TabChanged(int index) { if((index == tab_index_array[XML_FORMAT]) || (index == tab_index_array[DCEVENT_FORMAT])) { IgnoreConsecutiveCheckBox->setEnabled(TRUE); } if(index == tab_index_array[EDFPLUS_FORMAT]) { IgnoreConsecutiveCheckBox->setEnabled(FALSE); } if(index == tab_index_array[ASCIICSV_FORMAT]) { if(UseManualDescriptionRadioButton->isChecked() == TRUE) { IgnoreConsecutiveCheckBox->setEnabled(FALSE); } else { IgnoreConsecutiveCheckBox->setEnabled(TRUE); } } } void UI_ImportAnnotationswindow::DCEventSignalChanged(int index) { char scratchpad[64]; if((index < 0) || (!mainwindow->signalcomps)) { DCEventTriggerLevelSpinBox->setSuffix(""); return; } strcpy(scratchpad, " "); strcat(scratchpad, mainwindow->signalcomp[index]->physdimension); DCEventTriggerLevelSpinBox->setSuffix(scratchpad); } void UI_ImportAnnotationswindow::ImportButtonClicked() { int i, input_format, error=0; ImportAnnotsDialog->setEnabled(FALSE); i = tabholder->currentIndex(); for(input_format = 0; input_format < TAB_CNT; input_format++) { if(tab_index_array[input_format] == i) { break; } } if(input_format >= TAB_CNT) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Internal error (input_format >= TAB_CNT)."); messagewindow.exec(); ImportAnnotsDialog->setEnabled(TRUE); return; } mainwindow->import_annotations_var->format = input_format; if(input_format == DCEVENT_FORMAT) { error = import_from_dcevent(); } if(input_format == EDFPLUS_FORMAT) { error = import_from_edfplus(); } if(input_format == XML_FORMAT) { error = import_from_xml(); } if(input_format == ASCIICSV_FORMAT) { error = import_from_ascii(); } if(mainwindow->annotations_dock[0] == NULL) { mainwindow->annotations_dock[0] = new UI_Annotationswindow(0, mainwindow); mainwindow->addDockWidget(Qt::RightDockWidgetArea, mainwindow->annotations_dock[0]->docklist, Qt::Vertical); if(!mainwindow->annotationlist[0]) { mainwindow->annotations_dock[0]->docklist->hide(); } } if(mainwindow->annotationlist[0]) { mainwindow->annotations_dock[0]->docklist->show(); mainwindow->annotations_edited = 1; mainwindow->annotations_dock[0]->updateList(); mainwindow->save_act->setEnabled(TRUE); } mainwindow->maincurve->update(); if(!error) { QMessageBox messagewindow(QMessageBox::Information, "Ready", "Done."); messagewindow.setIconPixmap(QPixmap(":/images/ok.png")); messagewindow.exec(); } ImportAnnotsDialog->setEnabled(TRUE); if(!error) { ImportAnnotsDialog->close(); } } int UI_ImportAnnotationswindow::import_from_xml(void) { int i, j, digits, ignore_consecutive=0; char path[MAX_PATH_LENGTH], last_description[256], *result, duration[32]; long long onset=0LL, l_temp, utc_time=0LL; struct annotationblock *annotation; struct date_time_struct date_time; struct xml_handle *xml_hdl; duration[0] = 0; last_description[0] = 0; if(IgnoreConsecutiveCheckBox->checkState() == Qt::Checked) { ignore_consecutive = 1; } else { ignore_consecutive = 0; } strcpy(path, QFileDialog::getOpenFileName(0, "Open XML file", QString::fromLocal8Bit(mainwindow->recent_opendir), "XML files (*.xml *.XML)").toLocal8Bit().data()); if(!strcmp(path, "")) { return(1); } get_directory_from_path(mainwindow->recent_opendir, path, MAX_PATH_LENGTH); if(mainwindow->annotationlist_backup==NULL) { mainwindow->annotationlist_backup = edfplus_annotation_copy_list(&mainwindow->annotationlist[0]); } xml_hdl = xml_get_handle(path); if(xml_hdl==NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not open file for reading."); messagewindow.exec(); return(1); } if((xml_hdl->encoding != 1) && (xml_hdl->encoding != 2)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Encoding of XML-file must be UTF-8 or ISO-8859-1."); messagewindow.exec(); xml_close(xml_hdl); return(1); } if(strcmp(xml_hdl->elementname, "annotationlist")) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not find root element \"annotationlist\"."); messagewindow.exec(); xml_close(xml_hdl); return(1); } QApplication::setOverrideCursor(Qt::WaitCursor); for(j=0; j<10; j++) qApp->processEvents(); for(i=0; i<10000; i++) { if(xml_goto_nth_element_inside(xml_hdl, "annotation", i)) { if(i == 0) { QApplication::restoreOverrideCursor(); QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not find child element \"annotation\"."); messagewindow.exec(); xml_close(xml_hdl); return(1); } break; } if(xml_goto_nth_element_inside(xml_hdl, "onset", 0)) { xml_go_up(xml_hdl); continue; } result = xml_get_content_of_element(xml_hdl); if(strlen(result) > 17) { if((result[4] == '-') && (result[7] == '-') && (result[10] == 'T') && (result[13] == ':') && (result[16] == ':')) { date_time.year = atoi(result); date_time.month = atoi(result + 5); date_time.day = atoi(result + 8); date_time.hour = atoi(result + 11); date_time.minute = atoi(result + 14); date_time.second = atoi(result + 17); date_time_to_utc(&utc_time, date_time); onset = utc_time - mainwindow->edfheaderlist[0]->utc_starttime; onset *= TIME_DIMENSION; if(strlen(result) > 19) { if(result[19] == '.') { for(digits=0; digits<32; digits++) { if((result[20 + digits] < '0') || (result[20 + digits] > '9')) { break; } } result[20 + digits] = 0; if(digits) { l_temp = (atoi(result + 20) * TIME_DIMENSION); for(; digits>0; digits--) { l_temp /= 10LL; } onset += l_temp; } } else { xml_go_up(xml_hdl); continue; } } } } else { xml_go_up(xml_hdl); continue; } xml_go_up(xml_hdl); if(!xml_goto_nth_element_inside(xml_hdl, "duration", 0)) { result = xml_get_content_of_element(xml_hdl); strncpy(duration, result, 16); duration[15] = 0; if((!(is_number(duration))) && (duration[0] != '-')) { remove_trailing_zeros(duration); } else { duration[0] = 0; } free(result); xml_go_up(xml_hdl); } if(xml_goto_nth_element_inside(xml_hdl, "description", 0)) { xml_go_up(xml_hdl); continue; } result = xml_get_content_of_element(xml_hdl); if((!ignore_consecutive) || (strcmp(result, last_description))) { annotation = (struct annotationblock *)calloc(1, sizeof(struct annotationblock)); if(annotation == NULL) { QApplication::restoreOverrideCursor(); QMessageBox messagewindow(QMessageBox::Critical, "Error", "A memory allocation error occurred (annotation)."); messagewindow.exec(); free(result); xml_close(xml_hdl); return(1); } annotation->onset = onset; strncpy(annotation->annotation, result, MAX_ANNOTATION_LEN); if(xml_hdl->encoding == 1) { latin1_to_utf8(annotation->annotation, MAX_ANNOTATION_LEN); } annotation->annotation[MAX_ANNOTATION_LEN] = 0; strcpy(annotation->duration, duration); edfplus_annotation_add_item(&mainwindow->annotationlist[0], annotation); strcpy(last_description, result); } free(result); xml_go_up(xml_hdl); xml_go_up(xml_hdl); } xml_close(xml_hdl); QApplication::restoreOverrideCursor(); return(0); } int UI_ImportAnnotationswindow::import_from_ascii(void) { int i, j, temp, column, column_end, str_start, line_nr, startline=1, onset_column=1, descr_column=2, duration_column=3, onset_is_set, descr_is_set, duration_is_set, max_descr_length, onsettime_coding=0, digits, days=0, ignore_consecutive=0, use_duration=0, manualdescription; char path[MAX_PATH_LENGTH], line[2048], scratchpad[256], str[2048], separator=',', description[256], last_description[256], duration[32]; long long onset=0LL, l_temp, last_onset=0LL, utc_time=0LL; FILE *inputfile=NULL; struct annotationblock *annotation; struct date_time_struct date_time; max_descr_length = 20; description[0] = 0; duration[0] = 0; last_description[0] = 0; if(UseManualDescriptionRadioButton->isChecked() == TRUE) { manualdescription = 1; strcpy(description, DescriptionLineEdit->text().toLatin1().data()); } else { manualdescription = 0; } strcpy(str, SeparatorLineEdit->text().toLatin1().data()); if(!strcmp(str, "tab")) { separator = '\t'; } else { if(strlen(str)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Invalid input", "Separator must be one character or \"tab\"."); messagewindow.exec(); return(1); } if((str[0]<32)||(str[0]>126)) { QMessageBox messagewindow(QMessageBox::Critical, "Invalid input", "Separator character is not a valid ASCII character."); messagewindow.exec(); return(1); } if(str[0]=='.') { QMessageBox messagewindow(QMessageBox::Critical, "Invalid input", "Separator character can not be a dot."); messagewindow.exec(); return(1); } if((str[0]>47)&&(str[0]<58)) { QMessageBox messagewindow(QMessageBox::Critical, "Invalid input", "Separator character can not be a number."); messagewindow.exec(); return(1); } separator = str[0]; } strcpy(mainwindow->import_annotations_var->separator, str); startline = DatastartSpinbox->value(); descr_column = DescriptionColumnSpinBox->value() - 1; onset_column = OnsetColumnSpinBox->value() - 1; duration_column = DurationColumnSpinBox->value() - 1; onsettime_coding = RelativeTimeComboBox->currentIndex(); if(DurationCheckBox->checkState() == Qt::Checked) { use_duration = 1; } else { use_duration = 0; } if((descr_column == onset_column) && (!manualdescription)) { QMessageBox messagewindow(QMessageBox::Critical, "Invalid input", "Onset and Description can not be in the same column."); messagewindow.exec(); return(1); } if((duration_column == onset_column) && use_duration) { QMessageBox messagewindow(QMessageBox::Critical, "Invalid input", "Onset and Duration can not be in the same column."); messagewindow.exec(); return(1); } if((descr_column == duration_column) && (!manualdescription) && use_duration) { QMessageBox messagewindow(QMessageBox::Critical, "Invalid input", "Duration and Description can not be in the same column."); messagewindow.exec(); return(1); } mainwindow->import_annotations_var->onsettimeformat = onsettime_coding; mainwindow->import_annotations_var->onsetcolumn = onset_column + 1; mainwindow->import_annotations_var->descriptioncolumn = descr_column + 1; mainwindow->import_annotations_var->durationcolumn = duration_column + 1; mainwindow->import_annotations_var->useduration = use_duration; mainwindow->import_annotations_var->datastartline = startline; if(UseManualDescriptionRadioButton->isChecked() == TRUE) { mainwindow->import_annotations_var->manualdescription = 1; } else { mainwindow->import_annotations_var->manualdescription = 0; } strcpy(mainwindow->import_annotations_var->description, DescriptionLineEdit->text().toLatin1().data()); if(IgnoreConsecutiveCheckBox->checkState() == Qt::Checked) { ignore_consecutive = 1; } else { ignore_consecutive = 0; } mainwindow->import_annotations_var->ignoreconsecutive = ignore_consecutive; strcpy(path, QFileDialog::getOpenFileName(0, "Open ASCII file", QString::fromLocal8Bit(mainwindow->recent_opendir), "ASCII files (*.txt *.TXT *.csv *.CSV)").toLocal8Bit().data()); if(!strcmp(path, "")) { return(1); } get_directory_from_path(mainwindow->recent_opendir, path, MAX_PATH_LENGTH); if(mainwindow->annotationlist_backup==NULL) { mainwindow->annotationlist_backup = edfplus_annotation_copy_list(&mainwindow->annotationlist[0]); } inputfile = fopeno(path, "rb"); if(inputfile==NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not open file for reading."); messagewindow.exec(); return(1); } rewind(inputfile); QApplication::setOverrideCursor(Qt::WaitCursor); for(j=0; j<10; j++) qApp->processEvents(); for(i=0; i<(startline-1);) { temp = fgetc(inputfile); if(temp==EOF) { QApplication::restoreOverrideCursor(); QMessageBox messagewindow(QMessageBox::Critical, "Error", "File does not contain enough lines."); messagewindow.exec(); fclose(inputfile); return(1); } if(temp=='\n') { i++; } } i = 0; column = 0; column_end = 1; str_start = 0; line_nr = startline; onset_is_set = 0; descr_is_set = 0; duration_is_set = 0; while(1) { temp = fgetc(inputfile); if(temp==EOF) { break; } line[i] = temp; if(line[i]=='\r') { continue; } if(separator!=',') { if(line[i]==',') { line[i] = '.'; } } if(line[i]==separator) { line[i] = 0; if(!column_end) { if(column == onset_column) { onset = 0LL; strncpy(scratchpad, line + str_start, 30); scratchpad[30] = 0; if(onsettime_coding == 0) { onset = atoll_x(scratchpad, TIME_DIMENSION); onset += mainwindow->edfheaderlist[0]->starttime_offset; onset_is_set = 1; } if(onsettime_coding == 1) { if(strlen(scratchpad) > 6) { if((scratchpad[2] == ':') && (scratchpad[5] == ':')) { scratchpad[8] = 0; onset = atoi(scratchpad) * 3600LL; onset += (atoi(scratchpad + 3) * 60LL); onset += (long long)(atoi(scratchpad + 6)); onset *= TIME_DIMENSION; onset -= mainwindow->edfheaderlist[0]->l_starttime; if(onset < last_onset) { last_onset = onset; days++; } onset_is_set = 1; } } if(strlen(scratchpad) > 5) { if((scratchpad[1] == ':') && (scratchpad[4] == ':')) { scratchpad[7] = 0; onset = atoi(scratchpad) * 3600LL; onset += (atoi(scratchpad + 2) * 60LL); onset += (long long)(atoi(scratchpad + 5)); onset *= TIME_DIMENSION; onset -= mainwindow->edfheaderlist[0]->l_starttime; if(onset < last_onset) { last_onset = onset; days++; } onset_is_set = 1; } } } if(onsettime_coding == 2) { if(strlen(scratchpad) > 8) { if((scratchpad[2] == ':') && (scratchpad[5] == ':') && ((scratchpad[8] == '.') || (scratchpad[8] == ','))) { for(digits=0; digits<32; digits++) { if((scratchpad[9 + digits] < '0') || (scratchpad[9 + digits] > '9')) { break; } } scratchpad[9 + digits] = 0; onset = atoi(scratchpad) * 3600LL; onset += (atoi(scratchpad + 3) * 60LL); onset += (long long)(atoi(scratchpad + 6)); onset *= TIME_DIMENSION; if(digits) { l_temp = (atoi(scratchpad + 9) * TIME_DIMENSION); for(; digits>0; digits--) { l_temp /= 10LL; } onset += l_temp; } onset -= mainwindow->edfheaderlist[0]->l_starttime; if(onset < last_onset) { last_onset = onset; days++; } onset_is_set = 1; } } if(strlen(scratchpad) > 7) { if((scratchpad[1] == ':') && (scratchpad[4] == ':') && ((scratchpad[7] == '.') || (scratchpad[7] == ','))) { for(digits=0; digits<32; digits++) { if((scratchpad[8 + digits] < '0') || (scratchpad[8 + digits] > '9')) { break; } } scratchpad[8 + digits] = 0; onset = atoi(scratchpad) * 3600LL; onset += (atoi(scratchpad + 2) * 60LL); onset += (long long)(atoi(scratchpad + 5)); onset *= TIME_DIMENSION; if(digits) { l_temp = (atoi(scratchpad + 8) * TIME_DIMENSION); for(; digits>0; digits--) { l_temp /= 10LL; } onset += l_temp; } onset -= mainwindow->edfheaderlist[0]->l_starttime; if(onset < last_onset) { last_onset = onset; days++; } onset_is_set = 1; } } } if(onsettime_coding == 3) { if(strlen(scratchpad) > 17) { if((scratchpad[4] == '-') && (scratchpad[7] == '-') && (scratchpad[13] == ':') && (scratchpad[16] == ':')) { scratchpad[19] = 0; date_time.year = atoi(scratchpad); date_time.month = atoi(scratchpad + 5); date_time.day = atoi(scratchpad + 8); date_time.hour = atoi(scratchpad + 11); date_time.minute = atoi(scratchpad + 14); date_time.second = atoi(scratchpad + 17); date_time_to_utc(&utc_time, date_time); onset = utc_time - mainwindow->edfheaderlist[0]->utc_starttime; onset *= TIME_DIMENSION; onset_is_set = 1; } } } if(onsettime_coding == 4) { if(strlen(scratchpad) > 19) { if((scratchpad[4] == '-') && (scratchpad[7] == '-') && (scratchpad[13] == ':') && (scratchpad[16] == ':') && ((scratchpad[19] == ',') || (scratchpad[19] == '.'))) { for(digits=0; digits<32; digits++) { if((scratchpad[20 + digits] < '0') || (scratchpad[20 + digits] > '9')) { break; } } scratchpad[20 + digits] = 0; date_time.year = atoi(scratchpad); date_time.month = atoi(scratchpad + 5); date_time.day = atoi(scratchpad + 8); date_time.hour = atoi(scratchpad + 11); date_time.minute = atoi(scratchpad + 14); date_time.second = atoi(scratchpad + 17); date_time_to_utc(&utc_time, date_time); onset = utc_time - mainwindow->edfheaderlist[0]->utc_starttime; onset *= TIME_DIMENSION; if(digits) { l_temp = (atoi(scratchpad + 20) * TIME_DIMENSION); for(; digits>0; digits--) { l_temp /= 10LL; } onset += l_temp; } onset_is_set = 1; } } } } if((!manualdescription) && (column == descr_column)) { strncpy(description, line + str_start, max_descr_length); description[max_descr_length] = 0; latin1_to_utf8(description, max_descr_length); descr_is_set = 1; } if((use_duration) && (column == duration_column)) { strncpy(duration, line + str_start, 16); duration[15] = 0; duration_is_set = 1; } column_end = 1; column++; } } else { if(line[i]!='\n') { if(column_end) { str_start = i; column_end = 0; } } } if(line[i]=='\n') { line[i] = 0; if(!column_end) { if(column == onset_column) { if((descr_is_set) || (manualdescription)) { onset = 0LL; strncpy(scratchpad, line + str_start, 30); scratchpad[30] = 0; if(onsettime_coding == 0) { onset = atoll_x(scratchpad, TIME_DIMENSION); onset += mainwindow->edfheaderlist[0]->starttime_offset; onset_is_set = 1; } if(onsettime_coding == 1) { if(strlen(scratchpad) > 6) { if((scratchpad[2] == ':') && (scratchpad[5] == ':')) { scratchpad[8] = 0; onset = atoi(scratchpad) * 3600LL; onset += (atoi(scratchpad + 3) * 60LL); onset += (long long)(atoi(scratchpad + 6)); onset *= TIME_DIMENSION; onset -= mainwindow->edfheaderlist[0]->l_starttime; if(onset < last_onset) { last_onset = onset; days++; } onset_is_set = 1; } } if(strlen(scratchpad) > 5) { if((scratchpad[1] == ':') && (scratchpad[4] == ':')) { scratchpad[7] = 0; onset = atoi(scratchpad) * 3600LL; onset += (atoi(scratchpad + 2) * 60LL); onset += (long long)(atoi(scratchpad + 5)); onset *= TIME_DIMENSION; onset -= mainwindow->edfheaderlist[0]->l_starttime; if(onset < last_onset) { last_onset = onset; days++; } onset_is_set = 1; } } } if(onsettime_coding == 2) { if(strlen(scratchpad) > 8) { if((scratchpad[2] == ':') && (scratchpad[5] == ':') && ((scratchpad[8] == '.') || (scratchpad[8] == ','))) { for(digits=0; digits<32; digits++) { if((scratchpad[9 + digits] < '0') || (scratchpad[9 + digits] > '9')) { break; } } scratchpad[9 + digits] = 0; onset = atoi(scratchpad) * 3600LL; onset += (atoi(scratchpad + 3) * 60LL); onset += (long long)(atoi(scratchpad + 6)); onset *= TIME_DIMENSION; if(digits) { l_temp = (atoi(scratchpad + 9) * TIME_DIMENSION); for(; digits>0; digits--) { l_temp /= 10LL; } onset += l_temp; } onset -= mainwindow->edfheaderlist[0]->l_starttime; if(onset < last_onset) { last_onset = onset; days++; } onset_is_set = 1; } } if(strlen(scratchpad) > 7) { if((scratchpad[1] == ':') && (scratchpad[4] == ':') && ((scratchpad[7] == '.') || (scratchpad[7] == ','))) { for(digits=0; digits<32; digits++) { if((scratchpad[8 + digits] < '0') || (scratchpad[8 + digits] > '9')) { break; } } scratchpad[8 + digits] = 0; onset = atoi(scratchpad) * 3600LL; onset += (atoi(scratchpad + 2) * 60LL); onset += (long long)(atoi(scratchpad + 5)); onset *= TIME_DIMENSION; if(digits) { l_temp = (atoi(scratchpad + 8) * TIME_DIMENSION); for(; digits>0; digits--) { l_temp /= 10LL; } onset += l_temp; } onset -= mainwindow->edfheaderlist[0]->l_starttime; if(onset < last_onset) { last_onset = onset; days++; } onset_is_set = 1; } } } if(onsettime_coding == 3) { if(strlen(scratchpad) > 17) { if((scratchpad[4] == '-') && (scratchpad[7] == '-') && (scratchpad[13] == ':') && (scratchpad[16] == ':')) { scratchpad[19] = 0; date_time.year = atoi(scratchpad); date_time.month = atoi(scratchpad + 5); date_time.day = atoi(scratchpad + 8); date_time.hour = atoi(scratchpad + 11); date_time.minute = atoi(scratchpad + 14); date_time.second = atoi(scratchpad + 17); date_time_to_utc(&utc_time, date_time); onset = utc_time - mainwindow->edfheaderlist[0]->utc_starttime; onset *= TIME_DIMENSION; onset_is_set = 1; } } } if(onsettime_coding == 4) { if(strlen(scratchpad) > 19) { if((scratchpad[4] == '-') && (scratchpad[7] == '-') && (scratchpad[13] == ':') && (scratchpad[16] == ':') && ((scratchpad[19] == ',') || (scratchpad[19] == '.'))) { for(digits=0; digits<32; digits++) { if((scratchpad[20 + digits] < '0') || (scratchpad[20 + digits] > '9')) { break; } } scratchpad[20 + digits] = 0; date_time.year = atoi(scratchpad); date_time.month = atoi(scratchpad + 5); date_time.day = atoi(scratchpad + 8); date_time.hour = atoi(scratchpad + 11); date_time.minute = atoi(scratchpad + 14); date_time.second = atoi(scratchpad + 17); date_time_to_utc(&utc_time, date_time); onset = utc_time - mainwindow->edfheaderlist[0]->utc_starttime; onset *= TIME_DIMENSION; if(digits) { l_temp = (atoi(scratchpad + 20) * TIME_DIMENSION); for(; digits>0; digits--) { l_temp /= 10LL; } onset += l_temp; } onset_is_set = 1; } } } } } if((!manualdescription) && (column == descr_column)) { if(onset_is_set) { strncpy(description, line + str_start, max_descr_length); description[max_descr_length] = 0; latin1_to_utf8(description, max_descr_length); descr_is_set = 1; } } if((use_duration) && (column == duration_column)) { strncpy(duration, line + str_start, 15); duration[15] = 0; duration_is_set = 1; } } if((!use_duration) || duration_is_set) { if(onset_is_set && descr_is_set && (!manualdescription)) { if((!ignore_consecutive) || strcmp(description, last_description)) { annotation = (struct annotationblock *)calloc(1, sizeof(struct annotationblock)); if(annotation == NULL) { QApplication::restoreOverrideCursor(); QMessageBox messagewindow(QMessageBox::Critical, "Error", "A memory allocation error occurred (annotation)."); messagewindow.exec(); fclose(inputfile); return(1); } annotation->onset = onset + (86400LL * TIME_DIMENSION * days); strncpy(annotation->annotation, description, MAX_ANNOTATION_LEN); annotation->annotation[MAX_ANNOTATION_LEN] = 0; if(use_duration) { if((!(is_number(duration))) && (duration[0] != '-')) { remove_trailing_zeros(duration); if(duration[0] == '+') { strcpy(annotation->duration, duration + 1); } else { strcpy(annotation->duration, duration); } } } edfplus_annotation_add_item(&mainwindow->annotationlist[0], annotation); strcpy(last_description, description); } } if(onset_is_set && manualdescription) { annotation = (struct annotationblock *)calloc(1, sizeof(struct annotationblock)); if(annotation == NULL) { QApplication::restoreOverrideCursor(); QMessageBox messagewindow(QMessageBox::Critical, "Error", "A memory allocation error occurred (annotation)."); messagewindow.exec(); fclose(inputfile); return(1); } annotation->onset = onset + (86400LL * TIME_DIMENSION * days); strncpy(annotation->annotation, description, MAX_ANNOTATION_LEN); annotation->annotation[MAX_ANNOTATION_LEN] = 0; if(use_duration) { if((!(is_number(duration))) && (duration[0] != '-')) { remove_trailing_zeros(duration); if(duration[0] == '+') { strcpy(annotation->duration, duration + 1); } else { strcpy(annotation->duration, duration); } } } edfplus_annotation_add_item(&mainwindow->annotationlist[0], annotation); } } line_nr++; str_start = 0; i = 0; column = 0; column_end = 1; onset_is_set = 0; descr_is_set = 0; duration_is_set = 0; qApp->processEvents(); continue; } i++; if(i>2046) { QApplication::restoreOverrideCursor(); snprintf(scratchpad, 256, "Error, line %i is too long.\n", line_nr); QMessageBox messagewindow(QMessageBox::Critical, "Error", scratchpad); messagewindow.exec(); fclose(inputfile); return(1); } } QApplication::restoreOverrideCursor(); if(fclose(inputfile)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while closing inputfile."); messagewindow.exec(); return(1); } return(0); } int UI_ImportAnnotationswindow::import_from_edfplus(void) { int i, annotlist_size; char path[MAX_PATH_LENGTH], str[2048]; long long starttime_diff; FILE *inputfile=NULL; struct edfhdrblock *edfhdr=NULL; struct annotationblock *annotlist[1]; struct annotationblock *annotation; strcpy(path, QFileDialog::getOpenFileName(0, "Open EDF+/BDF+ file", QString::fromLocal8Bit(mainwindow->recent_opendir), "EDF/BDF files (*.edf *.EDF *.bdf *.BDF )").toLocal8Bit().data()); if(!strcmp(path, "")) { return(1); } get_directory_from_path(mainwindow->recent_opendir, path, MAX_PATH_LENGTH); if(mainwindow->annotationlist_backup==NULL) { mainwindow->annotationlist_backup = edfplus_annotation_copy_list(&mainwindow->annotationlist[0]); } inputfile = fopeno(path, "rb"); if(inputfile==NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not open file for reading."); messagewindow.exec(); return(1); } rewind(inputfile); EDFfileCheck EDFfilechecker; str[0] = 0; annotlist[0] = NULL; edfhdr = EDFfilechecker.check_edf_file(inputfile, str, 0); if(edfhdr==NULL) { strcat(str, "\n File is not a valid EDF or BDF file."); QMessageBox messagewindow(QMessageBox::Critical, "Error", str); messagewindow.exec(); fclose(inputfile); return(1); } if(!(edfhdr->edfplus || edfhdr->bdfplus)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "File is not an EDF+ or BDF+ file."); messagewindow.exec(); free(edfhdr->edfparam); free(edfhdr); fclose(inputfile); return(1); } strcpy(edfhdr->filename, path); edfhdr->file_hdl = inputfile; EDF_annotations annotations; annotations.get_annotations(0, edfhdr, &annotlist[0], mainwindow->read_nk_trigger_signal); if(edfhdr->annots_not_read) { edfplus_annotation_delete_list(&annotlist[0]); free(edfhdr->edfparam); free(edfhdr); fclose(inputfile); return(1); } annotlist_size = edfplus_annotation_count(&annotlist[0]); if(annotlist_size == 0) { QMessageBox messagewindow(QMessageBox::Information, "Import annotations", "No annotations found."); messagewindow.exec(); free(edfhdr->edfparam); free(edfhdr); fclose(inputfile); return(1); } starttime_diff = edfhdr->utc_starttime - mainwindow->edfheaderlist[mainwindow->sel_viewtime]->utc_starttime; starttime_diff *= TIME_DIMENSION; QApplication::setOverrideCursor(Qt::WaitCursor); for(i=0; ionset += starttime_diff; edfplus_annotation_add_copy(&mainwindow->annotationlist[0], annotation); } edfplus_annotation_sort(&mainwindow->annotationlist[0]); edfplus_annotation_delete_list(&annotlist[0]); free(edfhdr->edfparam); free(edfhdr); fclose(inputfile); QApplication::restoreOverrideCursor(); return(0); } int UI_ImportAnnotationswindow::import_from_dcevent(void) { int i, ignore_consecutive=0, signal_nr, smpls_per_datrec, bytes_per_datrec, recsize, jumpbytes, bufoffset, triggervalue, bitwidth, bitposition, trigger_sample, next_sample, eventcode, tmp_value=0, edfformat, annotations_found=0; char scratchpad[256], last_description[256], *buf; long long datrecs, trigger_datrec, time_per_sample, progress_steps; union { unsigned int one; signed int one_signed; unsigned short two[2]; signed short two_signed[2]; unsigned char four[4]; } var; FILE *inputfile=NULL; struct annotationblock *annotation; struct signalcompblock *signalcomp; last_description[0] = 0; if(IgnoreConsecutiveCheckBox->checkState() == Qt::Checked) { ignore_consecutive = 1; } else { ignore_consecutive = 0; } mainwindow->import_annotations_var->ignoreconsecutive = ignore_consecutive; signal_nr = DCEventSignalComboBox->currentIndex(); if(signal_nr < 0) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "You need to put at least one signal on the screen."); messagewindow.exec(); return(1); } if(mainwindow->signalcomp[signal_nr]->num_of_signals > 1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "The signal can not be a derivation of multiple signals."); messagewindow.exec(); return(1); } mainwindow->import_annotations_var->dceventbittime = BitTimeSpinbox->value(); mainwindow->import_annotations_var->triggerlevel = DCEventTriggerLevelSpinBox->value(); signalcomp = mainwindow->signalcomp[signal_nr]; smpls_per_datrec = signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].smp_per_record; recsize = signalcomp->edfhdr->recordsize; bufoffset = signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].buf_offset; time_per_sample = signalcomp->edfhdr->long_data_record_duration / smpls_per_datrec; if(signalcomp->edfhdr->edf) { edfformat = 1; bytes_per_datrec = smpls_per_datrec * 2; } else { bytes_per_datrec = smpls_per_datrec * 3; edfformat = 0; } jumpbytes = recsize - bytes_per_datrec; inputfile = signalcomp->edfhdr->file_hdl; bitwidth = ((long long)mainwindow->import_annotations_var->dceventbittime * 10000LL) / time_per_sample; if(bitwidth < 5) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Bit Time is set too low compared to the samplerate of the selected signal."); messagewindow.exec(); return(1); } triggervalue = mainwindow->import_annotations_var->triggerlevel / signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].bitvalue; triggervalue -= signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].offset; if(triggervalue >= signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].dig_max) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Trigger Level is equal or higher than physical maximum."); messagewindow.exec(); return(1); } if(triggervalue <= signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].dig_min) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Trigger Level is equal or lower than physical minimum."); messagewindow.exec(); return(1); } if(fseeko(inputfile, signalcomp->edfhdr->hdrsize + bufoffset, SEEK_SET)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while reading inputfile. (fseek)"); messagewindow.exec(); return(1); } buf = (char *)malloc(bytes_per_datrec); if(buf == NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "A memory allocation error occurred. (buf)"); messagewindow.exec(); return(1); } annotations_found = 0; QProgressDialog progress("Scanning file for DC-events...", "Abort", 0, (int)signalcomp->edfhdr->datarecords); progress.setWindowModality(Qt::WindowModal); progress.setMinimumDuration(200); progress_steps = signalcomp->edfhdr->datarecords / 100LL; if(progress_steps < 1LL) { progress_steps = 1LL; } /* BITPOSITION: 0 nothing (idle) 1 rising edge of startbit found 2 middle of startbit found 3 middle of bit 0 found ........................ 10 middle of bit 7 found 11 middle of stopbit found */ bitposition = 0; eventcode = 0; next_sample = 0; trigger_sample = 0; trigger_datrec = 0LL; for(datrecs=0LL; datrecs < signalcomp->edfhdr->datarecords; datrecs++) { if(annotations_found > 10000) { progress.reset(); break; } if(!(datrecs % progress_steps)) { progress.setValue((int)datrecs); qApp->processEvents(); if(progress.wasCanceled() == TRUE) { break; } } if(datrecs) { fseek(inputfile, jumpbytes, SEEK_CUR); } if(fread(buf, bytes_per_datrec, 1, inputfile) != 1) { progress.reset(); QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while reading inputfile. (fread)"); messagewindow.exec(); free(buf); return(1); } for(i=0; i triggervalue) { eventcode += (1 << (bitposition - 2)); } } if(bitposition == 10) { if(tmp_value < triggervalue) { sprintf(scratchpad, "Trigger ID=%i", eventcode); if((!ignore_consecutive) || (strcmp(scratchpad, last_description))) { annotation = (struct annotationblock *)calloc(1, sizeof(struct annotationblock)); if(annotation == NULL) { progress.reset(); QMessageBox messagewindow(QMessageBox::Critical, "Error", "A memory allocation error occurred (annotation)."); messagewindow.exec(); free(buf); return(1); } annotation->onset = ((trigger_datrec * signalcomp->edfhdr->long_data_record_duration) + (trigger_sample * time_per_sample)); annotation->onset += signalcomp->edfhdr->starttime_offset; annotation->file_num = signalcomp->edfhdr->file_num; strncpy(annotation->annotation, scratchpad, MAX_ANNOTATION_LEN); annotation->annotation[MAX_ANNOTATION_LEN] = 0; edfplus_annotation_add_item(&mainwindow->annotationlist[0], annotation); annotations_found++; strcpy(last_description, scratchpad); } } bitposition = 0; continue; } } next_sample = (i + bitwidth) % smpls_per_datrec; bitposition++; } } else { if(tmp_value > triggervalue) { trigger_sample = i; trigger_datrec = datrecs; bitposition = 1; next_sample = (i + (bitwidth / 2)) % smpls_per_datrec; eventcode = 0; } } } } free(buf); inputfile = NULL; progress.reset(); return(0); } edfbrowser_153_source/PaxHeaders.2978/annotations_dock.h0000644000175000001440000000012712251654530021661 xustar000000000000000029 mtime=1386699096.46603258 29 atime=1386699096.46603258 29 ctime=1386699096.46603258 edfbrowser_153_source/annotations_dock.h0000644000175000001440000000644212251654530021414 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef ANNOTATIONSFORM1_H #define ANNOTATIONSFORM1_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "mainwindow.h" #include "edit_annotation_dock.h" #include "viewcurve.h" #include "utils.h" #include "averager_dialog.h" #include "edf_annot_list.h" class UI_Mainwindow; class UI_Annotationswindow : public QObject { Q_OBJECT public: UI_Annotationswindow(int, QWidget *parent); UI_Mainwindow *mainwindow; QDockWidget *docklist; QListWidget *list; void updateList(void); private: struct annotationblock *annotation; int file_num, relative, selected, invert_filter, hide_nk_triggers, hide_bs_triggers; QDialog *dialog1; QHBoxLayout *h_layout; QVBoxLayout *v_layout; QCheckBox *checkbox1, *checkbox2; QLabel *label1; QLineEdit *lineedit1; QAction *show_between_act, *average_annot_act, *hide_annot_act, *unhide_annot_act, *hide_same_annots_act, *unhide_same_annots_act, *unhide_all_annots_act, *hide_all_NK_triggers_act, *hide_all_BS_triggers_act, *unhide_all_NK_triggers_act, *unhide_all_BS_triggers_act; private slots: void annotation_selected(QListWidgetItem *, int centered=1); void hide_editdock(bool); void checkbox1_clicked(int); void checkbox2_clicked(int); void show_between(bool); void average_annot(bool); void hide_annot(bool); void unhide_annot(bool); void hide_same_annots(bool); void unhide_same_annots(bool); void unhide_all_annots(bool); void filter_edited(const QString); void hide_all_NK_triggers(bool); void hide_all_BS_triggers(bool); void unhide_all_NK_triggers(bool); void unhide_all_BS_triggers(bool); }; #endif // ANNOTATIONSFORM1_H edfbrowser_153_source/PaxHeaders.2978/special_button.cpp0000644000175000001440000000013212251654530021666 xustar000000000000000030 mtime=1386699096.479032511 30 atime=1386699096.479032511 30 ctime=1386699096.479032511 edfbrowser_153_source/special_button.cpp0000644000175000001440000000467412251654530021432 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "special_button.h" SpecialButton::SpecialButton(QWidget *w_parent) : QWidget(w_parent) { ButtonColor = QColor(Qt::white); global_Color = Qt::white; buttonText[0] = 0; } void SpecialButton::paintEvent(QPaintEvent *) { int w, h; QPainter painter(this); painter.save(); w = width(); h = height(); painter.setRenderHint(QPainter::Antialiasing); painter.setPen(Qt::black); painter.drawRect(0, 0, w-1, h-1); painter.fillRect(1, 1, w-2, h-2, ButtonColor); if(buttonText[0]!=0) painter.drawText(5, h/2+5, buttonText); painter.restore(); } void SpecialButton::setColor(QColor newColor) { ButtonColor = newColor; update(); } QColor SpecialButton::color() { return(ButtonColor); } void SpecialButton::setGlobalColor(int newColor) { ButtonColor = (Qt::GlobalColor)newColor; global_Color = newColor; update(); } int SpecialButton::globalColor() { return(global_Color); } void SpecialButton::setText(const char *str) { strncpy(buttonText, str, 2047); buttonText[2047] = 0; update(); } void SpecialButton::mouseReleaseEvent(QMouseEvent *release_event) { if(release_event->button()==Qt::LeftButton) { emit clicked(this); } } edfbrowser_153_source/PaxHeaders.2978/emsa2edf.h0000644000175000001440000000013212251654530020006 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/emsa2edf.h0000644000175000001440000000412612251654530017542 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef UI_EMSA2EDFFORM_H #define UI_EMSA2EDFFORM_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "utils.h" class UI_EMSA2EDFwindow : public QObject { Q_OBJECT public: UI_EMSA2EDFwindow(char *recent_dir=NULL, char *save_dir=NULL); private: QPushButton *pushButton1, *pushButton2; QTextEdit *textEdit1; QDialog *myobjectDialog; char *recent_opendir, *recent_savedir; struct event_struct{ int onset; int duration; char description[80]; } *logbuf; int get_string(char *, FILE *, int, int); private slots: void SelectFileButton(); }; #endif edfbrowser_153_source/PaxHeaders.2978/print_to_edf.h0000644000175000001440000000013212251654530020774 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/print_to_edf.h0000644000175000001440000000322512251654530020527 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef PRINT_SCREEN_TO_EDF_H #define PRINT_SCREEN_TO_EDF_H #include #include #include #include #include #include #include #include #include "global.h" #include "mainwindow.h" #include "popup_messagewindow.h" #include "filter.h" #include "utc_date_time.h" #include "third_party/fidlib/fidlib.h" class UI_Mainwindow; void print_screen_to_edf(UI_Mainwindow *); #endif // PRINT_SCREEN_TO_EDF_H edfbrowser_153_source/PaxHeaders.2978/filter_dialog.h0000644000175000001440000000013212251654530021124 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/filter_dialog.h0000644000175000001440000000573612251654530020670 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * The current version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef ADD_FILTERFORM1_H #define ADD_FILTERFORM1_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "mainwindow.h" #include "filter.h" #include "popup_messagewindow.h" #include "filtercurve.h" #include "utils.h" #include "ravg_filter.h" #include "third_party/fidlib/fidlib.h" class UI_Mainwindow; class UI_FilterDialog : public QObject { Q_OBJECT public: UI_FilterDialog(QWidget *parent=0); UI_Mainwindow *mainwindow; private: QDialog *filterdialog; QPushButton *CancelButton, *ApplyButton; QListWidget *list; QComboBox *typebox, *modelbox; QDoubleSpinBox *freqbox, *ripplebox, *freq2box; QSpinBox *orderbox; QLabel *typeboxlabel, *freqboxlabel, *freqbox2label, *orderboxlabel, *modelboxlabel, *listlabel, *orderlabel, *ordervaluelabel; FilterCurve *curve1; double array[400], array_pha[400], last_ripple; int arraysize, last_order, last_qfactor, last_model, last_samples; void updatecurve(void); char *filter_spec, spec_str_1[256], spec_str_2[256]; private slots: void ApplyButtonClicked(); void frequencyboxvaluechanged(double); void orderboxvaluechanged(int); void filtertypeboxvaluechanged(int); void filtermodelboxvaluechanged(int); void rippleboxvaluechanged(double); void freq2boxvaluechanged(double); }; #endif // ADD_FILTERFORM1_H edfbrowser_153_source/PaxHeaders.2978/annotations_dock.cpp0000644000175000001440000000013212251654530022210 xustar000000000000000030 mtime=1386699096.476032527 30 atime=1386699096.476032527 30 ctime=1386699096.476032527 edfbrowser_153_source/annotations_dock.cpp0000644000175000001440000005344112251654530021750 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "annotations_dock.h" UI_Annotationswindow::UI_Annotationswindow(int file_number, QWidget *w_parent) { QPalette palette; mainwindow = (UI_Mainwindow *)w_parent; file_num = file_number; docklist = new QDockWidget("Annotations", w_parent); docklist->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); docklist->setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetMovable); palette.setColor(QPalette::Text, mainwindow->maincurve->text_color); palette.setColor(QPalette::Base, mainwindow->maincurve->backgroundcolor); relative = 1; selected = -1; invert_filter = 0; hide_nk_triggers = 0; hide_bs_triggers = 0; dialog1 = new QDialog; checkbox1 = new QCheckBox("Relative "); checkbox1->setGeometry(2, 2, 10, 10); checkbox1->setTristate(FALSE); checkbox1->setCheckState(Qt::Checked); label1 = new QLabel; label1->setText(" Filter:"); lineedit1 = new QLineEdit; lineedit1->setMaxLength(16); checkbox2 = new QCheckBox("Inv."); checkbox2->setGeometry(2, 2, 10, 10); checkbox2->setTristate(FALSE); checkbox2->setCheckState(Qt::Unchecked); list = new QListWidget(dialog1); list->setFont(*mainwindow->monofont); list->setAutoFillBackground(TRUE); list->setPalette(palette); show_between_act = new QAction("Set timescale from here to next annotation", list); hide_annot_act = new QAction("Hide", list); unhide_annot_act = new QAction("Unhide", list); hide_same_annots_act = new QAction("Hide similar", list); unhide_same_annots_act = new QAction("Unhide similar", list); unhide_all_annots_act = new QAction("Unhide all", list); average_annot_act = new QAction("Average", list); hide_all_NK_triggers_act = new QAction("Hide all Nihon Kohden triggers", list); hide_all_BS_triggers_act = new QAction("Hide all Biosemi triggers", list); unhide_all_NK_triggers_act = new QAction("Unhide all Nihon Kohden triggers", list); unhide_all_BS_triggers_act = new QAction("Unhide all Biosemi triggers", list); list->setContextMenuPolicy(Qt::ActionsContextMenu); list->insertAction(NULL, show_between_act); list->insertAction(NULL, hide_annot_act); list->insertAction(NULL, hide_same_annots_act); list->insertAction(NULL, unhide_annot_act); list->insertAction(NULL, unhide_same_annots_act); list->insertAction(NULL, unhide_all_annots_act); list->insertAction(NULL, average_annot_act); list->insertAction(NULL, hide_all_NK_triggers_act); list->insertAction(NULL, unhide_all_NK_triggers_act); list->insertAction(NULL, hide_all_BS_triggers_act); list->insertAction(NULL, unhide_all_BS_triggers_act); h_layout = new QHBoxLayout; h_layout->addWidget(checkbox1); h_layout->addWidget(label1); h_layout->addWidget(lineedit1); h_layout->addWidget(checkbox2); v_layout = new QVBoxLayout(dialog1); v_layout->addLayout(h_layout); v_layout->addWidget(list); v_layout->setSpacing(1); docklist->setWidget(dialog1); updateList(); QObject::connect(list, SIGNAL(itemPressed(QListWidgetItem *)), this, SLOT(annotation_selected(QListWidgetItem *))); QObject::connect(docklist, SIGNAL(visibilityChanged(bool)), this, SLOT(hide_editdock(bool))); QObject::connect(checkbox1, SIGNAL(stateChanged(int)), this, SLOT(checkbox1_clicked(int))); QObject::connect(checkbox2, SIGNAL(stateChanged(int)), this, SLOT(checkbox2_clicked(int))); QObject::connect(hide_annot_act, SIGNAL(triggered(bool)), this, SLOT(hide_annot(bool))); QObject::connect(unhide_annot_act, SIGNAL(triggered(bool)), this, SLOT(unhide_annot(bool))); QObject::connect(hide_same_annots_act, SIGNAL(triggered(bool)), this, SLOT(hide_same_annots(bool))); QObject::connect(unhide_same_annots_act, SIGNAL(triggered(bool)), this, SLOT(unhide_same_annots(bool))); QObject::connect(unhide_all_annots_act, SIGNAL(triggered(bool)), this, SLOT(unhide_all_annots(bool))); QObject::connect(average_annot_act, SIGNAL(triggered(bool)), this, SLOT(average_annot(bool))); QObject::connect(show_between_act, SIGNAL(triggered(bool)), this, SLOT(show_between(bool))); QObject::connect(hide_all_NK_triggers_act, SIGNAL(triggered(bool)), this, SLOT(hide_all_NK_triggers(bool))); QObject::connect(hide_all_BS_triggers_act, SIGNAL(triggered(bool)), this, SLOT(hide_all_BS_triggers(bool))); QObject::connect(unhide_all_NK_triggers_act, SIGNAL(triggered(bool)), this, SLOT(unhide_all_NK_triggers(bool))); QObject::connect(unhide_all_BS_triggers_act, SIGNAL(triggered(bool)), this, SLOT(unhide_all_BS_triggers(bool))); QObject::connect(lineedit1, SIGNAL(textEdited(const QString)), this, SLOT(filter_edited(const QString))); } void UI_Annotationswindow::hide_all_NK_triggers(bool) { struct annotationblock *annot; annot = mainwindow->annotationlist[file_num]; hide_nk_triggers = 1; while(annot != NULL) { if(annot->ident & (1 << ANNOT_ID_NK_TRIGGER)) { annot->hided = 1; annot->hided_in_list = 1; } annot = annot->next_annotation; } updateList(); mainwindow->maincurve->update(); } void UI_Annotationswindow::hide_all_BS_triggers(bool) { struct annotationblock *annot; annot = mainwindow->annotationlist[file_num]; hide_bs_triggers = 1; while(annot != NULL) { if(annot->ident & (1 << ANNOT_ID_BS_TRIGGER)) { annot->hided = 1; annot->hided_in_list = 1; } annot = annot->next_annotation; } updateList(); mainwindow->maincurve->update(); } void UI_Annotationswindow::unhide_all_NK_triggers(bool) { struct annotationblock *annot; annot = mainwindow->annotationlist[file_num]; hide_nk_triggers = 0; while(annot != NULL) { if(annot->ident & (1 << ANNOT_ID_NK_TRIGGER)) { annot->hided = 0; annot->hided_in_list = 0; } annot = annot->next_annotation; } updateList(); mainwindow->maincurve->update(); } void UI_Annotationswindow::unhide_all_BS_triggers(bool) { struct annotationblock *annot; annot = mainwindow->annotationlist[file_num]; hide_bs_triggers = 0; while(annot != NULL) { if(annot->ident & (1 << ANNOT_ID_BS_TRIGGER)) { annot->hided = 0; annot->hided_in_list = 0; } annot = annot->next_annotation; } updateList(); mainwindow->maincurve->update(); } void UI_Annotationswindow::filter_edited(const QString text) { int i, cnt, n, len; char filter_str[32]; struct annotationblock *annot; annot = mainwindow->annotationlist[file_num]; cnt = edfplus_annotation_count(&annot); if(cnt < 1) { return; } if(text.length() < 1) { while(annot != NULL) { if(!(((annot->ident & (1 << ANNOT_ID_NK_TRIGGER)) && hide_nk_triggers) || ((annot->ident & (1 << ANNOT_ID_BS_TRIGGER)) && hide_bs_triggers))) { annot->hided_in_list = 0; annot->hided = 0; } annot = annot->next_annotation; } updateList(); mainwindow->maincurve->update(); return; } strcpy(filter_str, lineedit1->text().toUtf8().data()); len = strlen(filter_str); if(invert_filter == 0) { while(annot != NULL) { if(!(((annot->ident & (1 << ANNOT_ID_NK_TRIGGER)) && hide_nk_triggers) || ((annot->ident & (1 << ANNOT_ID_BS_TRIGGER)) && hide_bs_triggers))) { annot->hided_in_list = 1; n = strlen(annot->annotation) - len + 1; for(i=0; iannotation + i, len))) { annot->hided_in_list = 0; annot->hided = 0; break; } } } annot = annot->next_annotation; } } else { while(annot != NULL) { if(!(((annot->ident & (1 << ANNOT_ID_NK_TRIGGER)) && hide_nk_triggers) || ((annot->ident & (1 << ANNOT_ID_BS_TRIGGER)) && hide_bs_triggers))) { annot->hided_in_list = 0; n = strlen(annot->annotation) - len + 1; for(i=0; iannotation + i, len))) { annot->hided_in_list = 1; annot->hided = 1; break; } } } annot = annot->next_annotation; } } updateList(); mainwindow->maincurve->update(); } void UI_Annotationswindow::checkbox2_clicked(int state) { int cnt, changed=0; struct annotationblock *annot; annot = mainwindow->annotationlist[file_num]; cnt = edfplus_annotation_count(&annot); if(cnt < 1) { return; } if(state==Qt::Checked) { if(invert_filter == 0) changed = 1; invert_filter = 1; } if(state==Qt::Unchecked) { if(invert_filter == 1) changed = 1; invert_filter = 0; } if(changed == 0) return; filter_edited(lineedit1->text()); } void UI_Annotationswindow::show_between(bool) { int n; long long displaytime; struct annotationblock *annot; if(list->count() < 2) { return; } annot = mainwindow->annotationlist[file_num]; n = list->currentRow(); if(n >= (list->count() - 1)) { return; } while(n--) { annot = annot->next_annotation; } displaytime = annot->onset; annot = annot->next_annotation; displaytime -= annot->onset; if(displaytime < 0) { displaytime *= -1; } if(displaytime < 1000) { return; } mainwindow->pagetime = displaytime; annotation_selected(list->currentItem(), 0); } void UI_Annotationswindow::hide_annot(bool) { int n; struct annotationblock *annot; if(list->count() < 1) { return; } annot = mainwindow->annotationlist[file_num]; n = list->currentRow(); while(n--) { annot = annot->next_annotation; } annot->hided_in_list = 1; annot->hided = 1; mainwindow->maincurve->update(); } void UI_Annotationswindow::unhide_annot(bool) { int n; struct annotationblock *annot; if(list->count() < 1) { return; } annot = mainwindow->annotationlist[file_num]; n = list->currentRow(); while(n--) { annot = annot->next_annotation; } annot->hided_in_list = 0; annot->hided = 0; mainwindow->maincurve->update(); } void UI_Annotationswindow::hide_same_annots(bool) { int n; char str1[MAX_ANNOTATION_LEN], str2[MAX_ANNOTATION_LEN]; struct annotationblock *annot; if(list->count() < 1) { return; } annot = mainwindow->annotationlist[file_num]; n = list->currentRow(); while(n--) { annot = annot->next_annotation; } strcpy(str1, annot->annotation); remove_leading_spaces(str1); remove_trailing_spaces(str1); annot = mainwindow->annotationlist[file_num]; while(annot != NULL) { strcpy(str2, annot->annotation); remove_leading_spaces(str2); remove_trailing_spaces(str2); if(!strcmp(str1, str2)) { annot->hided_in_list = 1; annot->hided = 1; } annot = annot->next_annotation; } mainwindow->maincurve->update(); } void UI_Annotationswindow::unhide_same_annots(bool) { int n; char str1[MAX_ANNOTATION_LEN], str2[MAX_ANNOTATION_LEN]; struct annotationblock *annot; if(list->count() < 1) { return; } annot = mainwindow->annotationlist[file_num]; n = list->currentRow(); while(n--) { annot = annot->next_annotation; } strcpy(str1, annot->annotation); remove_leading_spaces(str1); remove_trailing_spaces(str1); annot = mainwindow->annotationlist[file_num]; while(annot != NULL) { strcpy(str2, annot->annotation); remove_leading_spaces(str2); remove_trailing_spaces(str2); if(!strcmp(str1, str2)) { annot->hided_in_list = 0; annot->hided = 0; } annot = annot->next_annotation; } mainwindow->maincurve->update(); } void UI_Annotationswindow::unhide_all_annots(bool) { struct annotationblock *annot; annot = mainwindow->annotationlist[file_num]; while(annot != NULL) { annot->hided = 0; annot->hided_in_list = 0; annot = annot->next_annotation; } mainwindow->maincurve->update(); } void UI_Annotationswindow::average_annot(bool) { if(mainwindow->files_open != 1) { return; } if(!mainwindow->signalcomps) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "First add a signal to the screen."); messagewindow.exec(); return; } if(mainwindow->annot_editor_active) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Close the annotation editor and try again."); messagewindow.exec(); return; } if(list->count() < 1) { return; } UI_AveragerWindow average_wndw(mainwindow, list->currentRow()); } void UI_Annotationswindow::checkbox1_clicked(int state) { if(state==Qt::Checked) { relative = 1; } if(state==Qt::Unchecked) { relative = 0; } updateList(); } void UI_Annotationswindow::hide_editdock(bool visible) { if(visible==FALSE) { mainwindow->annotationEditDock->dockedit->hide(); } } 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_WS_X11 QFont specialfont("andale mono", 12, QFont::Normal, TRUE); specialfont.setPixelSize(12); #endif #ifdef Q_WS_MAC QFont specialfont("andale mono", 12, QFont::Normal, TRUE); specialfont.setPixelSize(12); #endif #ifdef Q_WS_WIN QFont specialfont("courier", 11, QFont::Normal, TRUE); specialfont.setPixelSize(12); #endif 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; ionset - 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_Annotationswindow::annotation_selected(QListWidgetItem * item, int centered) { int i=0, n; long long temp; annotation = mainwindow->annotationlist[file_num]; n = item->data(Qt::UserRole).toInt(); if(mainwindow->annot_editor_active) { mainwindow->annotationEditDock->set_selected_annotation(file_num, n); } while(n--) { annotation = annotation->next_annotation; } if(mainwindow->viewtime_sync==VIEWTIME_SYNCED_OFFSET) { for(i=0; ifiles_open; i++) { mainwindow->edfheaderlist[i]->viewtime = annotation->onset; if(centered) { mainwindow->edfheaderlist[i]->viewtime -= (mainwindow->pagetime / 2); } mainwindow->edfheaderlist[i]->viewtime -= mainwindow->edfheaderlist[file_num]->starttime_offset; } } if(mainwindow->viewtime_sync==VIEWTIME_UNSYNCED) { mainwindow->edfheaderlist[file_num]->viewtime = annotation->onset; if(centered) { mainwindow->edfheaderlist[file_num]->viewtime -= (mainwindow->pagetime / 2); } mainwindow->edfheaderlist[file_num]->viewtime -= mainwindow->edfheaderlist[file_num]->starttime_offset; } if((mainwindow->viewtime_sync==VIEWTIME_SYNCED_ABSOLUT)||(mainwindow->viewtime_sync==VIEWTIME_USER_DEF_SYNCED)) { temp = annotation->onset - mainwindow->edfheaderlist[file_num]->viewtime; temp -= mainwindow->edfheaderlist[file_num]->starttime_offset; if(centered) { temp -= (mainwindow->pagetime / 2); } for(i=0; ifiles_open; i++) { mainwindow->edfheaderlist[i]->viewtime += temp; } } if(mainwindow->annotationEditDock->dockedit->isVisible()==TRUE) { mainwindow->maincurve->setCrosshair_1_center(); } mainwindow->setup_viewbuf(); } edfbrowser_153_source/PaxHeaders.2978/jump_dialog.cpp0000644000175000001440000000013212251654530021145 xustar000000000000000030 mtime=1386699096.478032517 30 atime=1386699096.478032517 30 ctime=1386699096.478032517 edfbrowser_153_source/jump_dialog.cpp0000644000175000001440000002617412251654530020710 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "jump_dialog.h" UI_JumpMenuDialog::UI_JumpMenuDialog(QWidget *w_parent) { mainwindow = (UI_Mainwindow *)w_parent; jump_dialog = new QDialog(w_parent); jump_dialog->setMinimumSize(QSize(435, 200)); jump_dialog->setMaximumSize(QSize(435, 200)); jump_dialog->setWindowTitle("Jump to"); jump_dialog->setModal(TRUE); jump_dialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); label1 = new QLabel(jump_dialog); label1->setGeometry(QRect(10, 10, 155, 25)); label1->setText(" dd hh:mm:ss.ms "); daybox1 = new QSpinBox(jump_dialog); daybox1->setGeometry(QRect(10, 45, 45, 25)); daybox1->setRange(0, 30); daybox1->setEnabled(FALSE); daybox2 = new QSpinBox(jump_dialog); daybox2->setGeometry(QRect(10, 80, 45, 25)); daybox2->setRange(0, 30); daybox2->setEnabled(FALSE); timeEdit1 = new QTimeEdit(jump_dialog); timeEdit1->setGeometry(QRect(65, 45, 110, 25)); timeEdit1->setDisplayFormat("hh:mm:ss.zzz"); timeEdit1->setMinimumTime(QTime(0, 0, 0, 0)); timeEdit1->setEnabled(FALSE); timeEdit2 = new QTimeEdit(jump_dialog); timeEdit2->setGeometry(QRect(65, 80, 110, 25)); timeEdit2->setDisplayFormat("hh:mm:ss.zzz"); timeEdit2->setMinimumTime(QTime(0, 0, 0, 0)); timeEdit2->setEnabled(FALSE); label2 = new QLabel("Offset from start of recording", jump_dialog); label2->setGeometry(QRect(185, 45, 250, 25)); label3 = new QLabel("Absolute time", jump_dialog); label3->setGeometry(QRect(185, 80, 250, 25)); jumpButton = new QPushButton(jump_dialog); jumpButton->setGeometry(QRect(10, 165, 100, 25)); jumpButton->setText("Jump"); jumpButton->setEnabled(FALSE); CloseButton = new QPushButton(jump_dialog); CloseButton->setGeometry(QRect(325, 165, 100, 25)); CloseButton->setText("Cancel"); if(mainwindow->files_open) { daybox1->setEnabled(TRUE); daybox2->setEnabled(TRUE); timeEdit1->setEnabled(TRUE); timeEdit2->setEnabled(TRUE); starttime = mainwindow->edfheaderlist[mainwindow->sel_viewtime]->l_starttime + mainwindow->edfheaderlist[mainwindow->sel_viewtime]->starttime_offset; starttime /= 10000; time2.setHMS((int)((starttime / 3600000LL) % 24LL), (int)((starttime % 3600000LL) / 60000LL), (int)((starttime % 60000LL) / 1000LL), (int)(starttime % 1000LL)); timeEdit2->setMinimumTime(QTime((int)((starttime / 3600000LL) % 24LL), (int)((starttime % 3600000LL) / 60000LL), (int)((starttime % 60000LL) / 1000LL), (int)(starttime % 1000LL))); timeEdit2->setTime(time2); recording_duration = mainwindow->edfheaderlist[0]->datarecords * mainwindow->edfheaderlist[0]->long_data_record_duration; recording_duration /= (TIME_DIMENSION / 1000LL); jumpButton->setEnabled(TRUE); } QObject::connect(CloseButton, SIGNAL(clicked()), jump_dialog, SLOT(close())); QObject::connect(jumpButton, SIGNAL(clicked()), this, SLOT(jumpbutton_pressed())); QObject::connect(timeEdit1, SIGNAL(timeChanged(const QTime &)), this, SLOT(offsettime_changed(const QTime &))); QObject::connect(timeEdit2, SIGNAL(timeChanged(const QTime &)), this, SLOT(absolutetime_changed(const QTime &))); QObject::connect(daybox1, SIGNAL(valueChanged(int)), this, SLOT(offsetday_changed(int))); QObject::connect(daybox2, SIGNAL(valueChanged(int)), this, SLOT(absoluteday_changed(int))); jump_dialog->exec(); } void UI_JumpMenuDialog::offsetday_changed(int days) { long long milliseconds; if(!mainwindow->files_open) return; QObject::disconnect(daybox2, SIGNAL(valueChanged(int)), this, SLOT(absoluteday_changed(int))); QObject::disconnect(timeEdit2, SIGNAL(timeChanged(const QTime &)), this, SLOT(absolutetime_changed(const QTime &))); milliseconds = (long long)(timeEdit1->time().hour()) * 3600000LL; milliseconds += (long long)(timeEdit1->time().minute()) * 60000LL; milliseconds += (long long)(timeEdit1->time().second()) * 1000LL; milliseconds += (long long)(timeEdit1->time().msec()); milliseconds += ((long long)days * 86400000LL); milliseconds += starttime; time2.setHMS((int)((milliseconds / 3600000LL) % 24LL), (int)((milliseconds % 3600000LL) / 60000LL), (int)((milliseconds % 60000LL) / 1000LL), (int)(milliseconds % 1000LL)); timeEdit2->setTime(time2); daybox2->setValue((int)(milliseconds / 86400000LL)); QObject::connect(daybox2, SIGNAL(valueChanged(int)), this, SLOT(absoluteday_changed(int))); QObject::connect(timeEdit2, SIGNAL(timeChanged(const QTime &)), this, SLOT(absolutetime_changed(const QTime &))); } void UI_JumpMenuDialog::absoluteday_changed(int days) { long long milliseconds; if(!mainwindow->files_open) return; QObject::disconnect(daybox1, SIGNAL(valueChanged(int)), this, SLOT(offsetday_changed(int))); QObject::disconnect(timeEdit1, SIGNAL(timeChanged(const QTime &)), this, SLOT(offsettime_changed(const QTime &))); milliseconds = (long long)(timeEdit2->time().hour()) * 3600000LL; milliseconds += (long long)(timeEdit2->time().minute()) * 60000LL; milliseconds += (long long)(timeEdit2->time().second()) * 1000LL; milliseconds += (long long)(timeEdit2->time().msec()); milliseconds += ((long long)days * 86400000LL); if(milliseconds<0) milliseconds = 0; milliseconds -= starttime; time1.setHMS((int)((milliseconds / 3600000LL) % 24LL), (int)((milliseconds % 3600000LL) / 60000LL), (int)((milliseconds % 60000LL) / 1000LL), (int)(milliseconds % 1000LL)); timeEdit1->setTime(time1); daybox1->setValue((int)(milliseconds / 86400000LL)); QObject::connect(daybox1, SIGNAL(valueChanged(int)), this, SLOT(offsetday_changed(int))); QObject::connect(timeEdit1, SIGNAL(timeChanged(const QTime &)), this, SLOT(offsettime_changed(const QTime &))); } void UI_JumpMenuDialog::offsettime_changed(const QTime &time_1) { long long milliseconds; if(!mainwindow->files_open) return; QObject::disconnect(daybox2, SIGNAL(valueChanged(int)), this, SLOT(absoluteday_changed(int))); QObject::disconnect(timeEdit2, SIGNAL(timeChanged(const QTime &)), this, SLOT(absolutetime_changed(const QTime &))); milliseconds = (long long)(time_1.hour()) * 3600000LL; milliseconds += (long long)(time_1.minute()) * 60000LL; milliseconds += (long long)(time_1.second()) * 1000LL; milliseconds += (long long)(time_1.msec()); milliseconds += ((long long)daybox1->value() * 86400000LL); milliseconds += starttime; time2.setHMS((int)((milliseconds / 3600000LL) % 24LL), (int)((milliseconds % 3600000LL) / 60000LL), (int)((milliseconds % 60000LL) / 1000LL), (int)(milliseconds % 1000LL)); timeEdit2->setTime(time2); daybox2->setValue((int)(milliseconds / 86400000LL)); QObject::connect(daybox2, SIGNAL(valueChanged(int)), this, SLOT(absoluteday_changed(int))); QObject::connect(timeEdit2, SIGNAL(timeChanged(const QTime &)), this, SLOT(absolutetime_changed(const QTime &))); } void UI_JumpMenuDialog::absolutetime_changed(const QTime &time_2) { long long milliseconds; if(!mainwindow->files_open) return; QObject::disconnect(daybox1, SIGNAL(valueChanged(int)), this, SLOT(offsetday_changed(int))); QObject::disconnect(timeEdit1, SIGNAL(timeChanged(const QTime &)), this, SLOT(offsettime_changed(const QTime &))); milliseconds = (long long)(time_2.hour()) * 3600000LL; milliseconds += (long long)(time_2.minute()) * 60000LL; milliseconds += (long long)(time_2.second()) * 1000LL; milliseconds += (long long)(time_2.msec()); milliseconds += ((long long)daybox2->value() * 86400000LL); if(milliseconds<0) milliseconds = 0; milliseconds -= starttime; time1.setHMS((int)((milliseconds / 3600000LL) % 24LL), (int)((milliseconds % 3600000LL) / 60000LL), (int)((milliseconds % 60000LL) / 1000LL), (int)(milliseconds % 1000LL)); timeEdit1->setTime(time1); daybox1->setValue((int)(milliseconds / 86400000LL)); QObject::connect(daybox1, SIGNAL(valueChanged(int)), this, SLOT(offsetday_changed(int))); QObject::connect(timeEdit1, SIGNAL(timeChanged(const QTime &)), this, SLOT(offsettime_changed(const QTime &))); } void UI_JumpMenuDialog::jumpbutton_pressed() { int i; long long milliseconds; if(!mainwindow->files_open) return; milliseconds = (long long)(timeEdit1->time().hour()) * 3600000LL; milliseconds += (long long)(timeEdit1->time().minute()) * 60000LL; milliseconds += (long long)(timeEdit1->time().second()) * 1000LL; milliseconds += (long long)(timeEdit1->time().msec()); milliseconds += ((long long)daybox1->value() * 86400000LL); if(mainwindow->viewtime_sync==VIEWTIME_SYNCED_OFFSET) { for(i=0; ifiles_open; i++) { mainwindow->edfheaderlist[i]->viewtime = milliseconds * (TIME_DIMENSION / 1000); } } if(mainwindow->viewtime_sync==VIEWTIME_UNSYNCED) { mainwindow->edfheaderlist[mainwindow->sel_viewtime]->viewtime = milliseconds * (TIME_DIMENSION / 1000); } if(mainwindow->viewtime_sync==VIEWTIME_SYNCED_ABSOLUT) { mainwindow->edfheaderlist[mainwindow->sel_viewtime]->viewtime = milliseconds * (TIME_DIMENSION / 1000); for(i=0; ifiles_open; i++) { if(i!=mainwindow->sel_viewtime) { mainwindow->edfheaderlist[i]->viewtime = mainwindow->edfheaderlist[mainwindow->sel_viewtime]->viewtime - ((mainwindow->edfheaderlist[i]->utc_starttime - mainwindow->edfheaderlist[mainwindow->sel_viewtime]->utc_starttime) * TIME_DIMENSION); } } } if(mainwindow->viewtime_sync==VIEWTIME_USER_DEF_SYNCED) { for(i=0; ifiles_open; i++) { if(i!=mainwindow->sel_viewtime) { mainwindow->edfheaderlist[i]->viewtime -= (mainwindow->edfheaderlist[mainwindow->sel_viewtime]->viewtime - milliseconds * (TIME_DIMENSION / 1000)); } } mainwindow->edfheaderlist[mainwindow->sel_viewtime]->viewtime = milliseconds * (TIME_DIMENSION / 1000); } mainwindow->setup_viewbuf(); jump_dialog->close(); } edfbrowser_153_source/PaxHeaders.2978/load_montage_dialog.cpp0000644000175000001440000000013212251654530022623 xustar000000000000000030 mtime=1386699096.478032517 30 atime=1386699096.478032517 30 ctime=1386699096.478032517 edfbrowser_153_source/load_montage_dialog.cpp0000644000175000001440000011543312251654530022363 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "load_montage_dialog.h" UI_LoadMontagewindow::UI_LoadMontagewindow(QWidget *w_parent, char *path) { int i; mainwindow = (UI_Mainwindow *)w_parent; mtg_path[0] = 0; if(path!=NULL) { strcpy(mtg_path, path); } if(mainwindow->files_open==1) { LoadMontageDialog = NULL; LoadButtonClicked(); return; } LoadMontageDialog = new QDialog; LoadMontageDialog->setMinimumSize(QSize(800, 180)); LoadMontageDialog->setMaximumSize(QSize(800, 180)); LoadMontageDialog->setWindowTitle("Load montage"); LoadMontageDialog->setModal(TRUE); LoadMontageDialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); label1 = new QLabel(LoadMontageDialog); label1->setGeometry(QRect(10, 10, 780, 25)); label1->setText("Choose to which file you want to apply the montage:"); filelist = new QListWidget(LoadMontageDialog); filelist->setGeometry(QRect(10, 35, 780, 75)); filelist->setSelectionBehavior(QAbstractItemView::SelectRows); filelist->setSelectionMode(QAbstractItemView::SingleSelection); for(i=0; ifiles_open; i++) { new QListWidgetItem(QString::fromLocal8Bit(mainwindow->edfheaderlist[i]->filename), filelist); } LoadButton = new QPushButton(LoadMontageDialog); LoadButton->setGeometry(QRect(10, 140, 100, 25)); LoadButton->setText("Load"); CloseButton = new QPushButton(LoadMontageDialog); CloseButton->setGeometry(QRect(690, 140, 100, 25)); CloseButton->setText("Close"); QObject::connect(CloseButton, SIGNAL(clicked()), LoadMontageDialog, SLOT(close())); QObject::connect(LoadButton, SIGNAL(clicked()), this, SLOT(LoadButtonClicked())); filelist->setCurrentRow(mainwindow->files_open - 1); LoadMontageDialog->exec(); } void UI_LoadMontagewindow::LoadButtonClicked() { int i, k, n, p, tmp, skip, found, signalcomps_read=0, signals_read, signal_cnt, filters_read, filter_cnt=0, ravg_filter_cnt=0, fidfilter_cnt=0, len, order=1, type=0, model=0, size=0, amp_cat[3], f_ruler_cnt=0; char *result, scratchpad[2048], str[128], *err, *filter_spec, spec_str[256]; double frequency=1.0, frequency2=2.0, ripple=1.0; struct xml_handle *xml_hdl; struct signalcompblock *newsignalcomp; if(mainwindow->files_open==1) n = 0; else n = filelist->currentRow(); if(mtg_path[0]==0) { strcpy(mtg_path, QFileDialog::getOpenFileName(0, "Load montage", QString::fromLocal8Bit(mainwindow->recent_montagedir), "Montage files (*.mtg *.MTG)").toLocal8Bit().data()); if(!strcmp(mtg_path, "")) { return; } get_directory_from_path(mainwindow->recent_montagedir, mtg_path, MAX_PATH_LENGTH); } xml_hdl = xml_get_handle(mtg_path); if(xml_hdl==NULL) { sprintf(scratchpad, "Can not open montage file:\n%s", mtg_path); QMessageBox messagewindow(QMessageBox::Critical, "Error", QString::fromLocal8Bit(scratchpad)); messagewindow.exec(); mainwindow->remove_recent_file_mtg_path(mtg_path); return; } if(strcmp(xml_hdl->elementname, PROGRAM_NAME "_montage")) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There seems to be an error in this montage file."); messagewindow.exec(); xml_close(xml_hdl); return; } //////////////////////////////////////////// for(k=0; ksignalcomps; ) { if(mainwindow->signalcomp[k]->filenum==n) { if(mainwindow->spectrumdock->signalcomp == mainwindow->signalcomp[k]) { mainwindow->spectrumdock->clear(); mainwindow->spectrumdock->dock->hide(); } for(i=0; isignalcomp[k]->spectr_dialog[i]; if(p != 0) { delete mainwindow->spectrumdialog[p - 1]; mainwindow->spectrumdialog[p - 1] = NULL; } } for(i=0; isignalcomp[k]->avg_dialog[i]; if(p != 0) { delete mainwindow->averagecurvedialog[p - 1]; mainwindow->averagecurvedialog[p - 1] = NULL; } } if(mainwindow->signalcomp[k]->hascursor2) { /* crosshair_2_active = 0; crosshair_2_moving = 0;*/ } if(mainwindow->signalcomp[k]->hascursor1) { // crosshair_1_active = 0; // crosshair_2_active = 0; // crosshair_1_moving = 0; // crosshair_2_moving = 0; for(i=0; isignalcomps; i++) { mainwindow->signalcomp[i]->hascursor2 = 0; } } for(i=0; isignalcomp[k]->filter_cnt; i++) { free(mainwindow->signalcomp[k]->filter[i]); } mainwindow->signalcomp[k]->filter_cnt = 0; for(i=0; isignalcomp[k]->ravg_filter_cnt; i++) { free_ravg_filter(mainwindow->signalcomp[k]->ravg_filter[i]); } mainwindow->signalcomp[k]->ravg_filter_cnt = 0; for(i=0; isignalcomp[k]->fidfilter_cnt; i++) { free(mainwindow->signalcomp[k]->fidfilter[i]); fid_run_free(mainwindow->signalcomp[k]->fid_run[i]); fid_run_freebuf(mainwindow->signalcomp[k]->fidbuf[i]); fid_run_freebuf(mainwindow->signalcomp[k]->fidbuf2[i]); } mainwindow->signalcomp[k]->fidfilter_cnt = 0; if(mainwindow->signalcomp[k]->ecg_filter != NULL) { free_ecg_filter(mainwindow->signalcomp[k]->ecg_filter); mainwindow->signalcomp[k]->ecg_filter = NULL; strcpy(mainwindow->signalcomp[k]->signallabel, mainwindow->signalcomp[k]->signallabel_bu); mainwindow->signalcomp[k]->signallabellen = mainwindow->signalcomp[k]->signallabellen_bu; } free(mainwindow->signalcomp[k]); for(i=k; isignalcomps - 1; i++) { mainwindow->signalcomp[i] = mainwindow->signalcomp[i + 1]; } mainwindow->signalcomps--; k = 0; } else { k++; } } //////////////////////////////////////////// while(1) { skip = 0; xml_goto_root(xml_hdl); signals_read = 0; if(xml_goto_nth_element_inside(xml_hdl, "signalcomposition", signalcomps_read)) { break; } newsignalcomp = (struct signalcompblock *)calloc(1, sizeof(struct signalcompblock)); if(newsignalcomp==NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Internal error: Memory allocation error:\n\"new signal composition\""); messagewindow.exec(); xml_close(xml_hdl); return; } if(xml_goto_nth_element_inside(xml_hdl, "num_of_signals", 0)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There seems to be an error in this montage file."); messagewindow.exec(); free(newsignalcomp); xml_close(xml_hdl); return; } result = xml_get_content_of_element(xml_hdl); signal_cnt = atoi(result); free(result); if((signal_cnt<1)||(signal_cnt>MAXSIGNALS)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There seems to be an error in this montage file."); messagewindow.exec(); free(newsignalcomp); xml_close(xml_hdl); return; } newsignalcomp->edfhdr = mainwindow->edfheaderlist[n]; newsignalcomp->filenum = n; newsignalcomp->num_of_signals = signal_cnt; newsignalcomp->hascursor1 = 0; newsignalcomp->hascursor2 = 0; newsignalcomp->hasoffsettracking = 0; newsignalcomp->hasgaintracking = 0; newsignalcomp->screen_offset = 0; newsignalcomp->filter_cnt = 0; newsignalcomp->ravg_filter_cnt = 0; newsignalcomp->ecg_filter = NULL; newsignalcomp->fidfilter_cnt = 0; newsignalcomp->hasruler = 0; newsignalcomp->polarity = 1; xml_go_up(xml_hdl); if(!(xml_goto_nth_element_inside(xml_hdl, "alias", 0))) { result = xml_get_content_of_element(xml_hdl); if(result[0] != 0) { strncpy(newsignalcomp->alias, result, 16); newsignalcomp->alias[16] = 0; latin1_to_ascii(newsignalcomp->alias, 16); remove_trailing_spaces(newsignalcomp->alias); remove_leading_spaces(newsignalcomp->alias); } free(result); xml_go_up(xml_hdl); } if(xml_goto_nth_element_inside(xml_hdl, "voltpercm", 0)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There seems to be an error in this montage file."); messagewindow.exec(); free(newsignalcomp); xml_close(xml_hdl); return; } result = xml_get_content_of_element(xml_hdl); newsignalcomp->voltpercm = atof(result); if(newsignalcomp->voltpercm==0.0) newsignalcomp->voltpercm = 0.000000001; free(result); xml_go_up(xml_hdl); if(xml_goto_nth_element_inside(xml_hdl, "screen_offset", 0)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There seems to be an error in this montage file."); messagewindow.exec(); free(newsignalcomp); xml_close(xml_hdl); return; } result = xml_get_content_of_element(xml_hdl); newsignalcomp->screen_offset = atof(result); free(result); xml_go_up(xml_hdl); if(!(xml_goto_nth_element_inside(xml_hdl, "polarity", 0))) { result = xml_get_content_of_element(xml_hdl); newsignalcomp->polarity = atoi(result); if(newsignalcomp->polarity != -1) { newsignalcomp->polarity = 1; } free(result); xml_go_up(xml_hdl); } if(xml_goto_nth_element_inside(xml_hdl, "color", 0)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There seems to be an error in this montage file."); messagewindow.exec(); free(newsignalcomp); xml_close(xml_hdl); return; } result = xml_get_content_of_element(xml_hdl); newsignalcomp->color = atoi(result); if((newsignalcomp->color < 2) || (newsignalcomp->color > 18)) { newsignalcomp->color = 2; } free(result); xml_go_up(xml_hdl); if(!(xml_goto_nth_element_inside(xml_hdl, "filter_cnt", 0))) { result = xml_get_content_of_element(xml_hdl); filter_cnt = atoi(result); if(filter_cnt < 0) filter_cnt = 0; if(filter_cnt > MAXFILTERS) filter_cnt = MAXFILTERS; free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "ravg_filter_cnt", 0))) { result = xml_get_content_of_element(xml_hdl); ravg_filter_cnt = atoi(result); if(ravg_filter_cnt < 0) filter_cnt = 0; if(ravg_filter_cnt > MAXFILTERS) ravg_filter_cnt = MAXFILTERS; free(result); xml_go_up(xml_hdl); } if(filter_cnt) { fidfilter_cnt = 0; } else { if(!(xml_goto_nth_element_inside(xml_hdl, "fidfilter_cnt", 0))) { result = xml_get_content_of_element(xml_hdl); fidfilter_cnt = atoi(result); if(fidfilter_cnt < 0) fidfilter_cnt = 0; if(fidfilter_cnt > MAXFILTERS) fidfilter_cnt = MAXFILTERS; free(result); xml_go_up(xml_hdl); } } for(signals_read=0; signals_readfactor[signals_read] = atoi(result); if(newsignalcomp->factor[signals_read] < -128) { newsignalcomp->factor[signals_read] = -128; } if(newsignalcomp->factor[signals_read] > 128) { newsignalcomp->factor[signals_read] = 128; } if(newsignalcomp->factor[signals_read] == 0) { newsignalcomp->factor[signals_read] = 1; } free(result); xml_go_up(xml_hdl); if(xml_goto_nth_element_inside(xml_hdl, "edfindex", 0)) { if(xml_goto_nth_element_inside(xml_hdl, "label", 0)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There seems to be an error in this montage file."); messagewindow.exec(); free(newsignalcomp); xml_close(xml_hdl); return; } result = xml_get_content_of_element(xml_hdl); remove_trailing_spaces(result); found = 0; for(i=0; iedfhdr->edfsignals; i++) { strcpy(scratchpad, newsignalcomp->edfhdr->edfparam[i].label); remove_trailing_spaces(scratchpad); if(!strcmp(scratchpad, result)) { newsignalcomp->edfsignal[signals_read] = i; if(newsignalcomp->edfhdr->edfparam[newsignalcomp->edfsignal[signals_read]].annotation) { found = 0; } else { found = 1; } break; } } } else { result = xml_get_content_of_element(xml_hdl); newsignalcomp->edfsignal[signals_read] = atoi(result); if((newsignalcomp->edfsignal[signals_read] < 0) || (newsignalcomp->edfsignal[signals_read] >= newsignalcomp->edfhdr->edfsignals)) { found = 0; } else { if(newsignalcomp->edfhdr->edfparam[newsignalcomp->edfsignal[signals_read]].annotation) { found = 0; } else { found = 1; } } } free(result); if(!found) { free(newsignalcomp); skip = 1; signalcomps_read++; xml_go_up(xml_hdl); xml_go_up(xml_hdl); break; } if(signals_read) { if(newsignalcomp->edfhdr->edfparam[newsignalcomp->edfsignal[signals_read]].smp_per_record != newsignalcomp->edfhdr->edfparam[newsignalcomp->edfsignal[0]].smp_per_record) { free(newsignalcomp); skip = 1; signalcomps_read++; xml_go_up(xml_hdl); xml_go_up(xml_hdl); break; } } newsignalcomp->sensitivity[signals_read] = newsignalcomp->edfhdr->edfparam[newsignalcomp->edfsignal[signals_read]].bitvalue / (newsignalcomp->voltpercm * mainwindow->pixelsizefactor); if(!signals_read) { newsignalcomp->signallabel[0] = 0; } if(signal_cnt>1) { if(newsignalcomp->factor[signals_read]<0) { strcat(newsignalcomp->signallabel, "- "); } else { if(signals_read) { strcat(newsignalcomp->signallabel, "+ "); } } } strcpy(str, newsignalcomp->edfhdr->edfparam[newsignalcomp->edfsignal[signals_read]].label); strip_types_from_label(str); strcat(newsignalcomp->signallabel, str); strcat(newsignalcomp->signallabel, " "); len = strlen(newsignalcomp->signallabel); for(k=(len-1); k>0; k--) { if(newsignalcomp->signallabel[k]!=' ') break; } newsignalcomp->signallabel[k+2] = 0; newsignalcomp->file_duration = newsignalcomp->edfhdr->long_data_record_duration * newsignalcomp->edfhdr->datarecords; newsignalcomp->signallabellen = strlen(newsignalcomp->signallabel); xml_go_up(xml_hdl); xml_go_up(xml_hdl); } if(skip) continue; strcpy(newsignalcomp->physdimension, newsignalcomp->edfhdr->edfparam[newsignalcomp->edfsignal[0]].physdimension); remove_trailing_spaces(newsignalcomp->physdimension); for(filters_read=0; filters_read 1) || (frequency < 0.0001)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There seems to be an error in this montage file. (filter values)"); messagewindow.exec(); free(newsignalcomp); xml_close(xml_hdl); return; } if(frequency >= ((newsignalcomp->edfhdr->edfparam[newsignalcomp->edfsignal[0]].smp_per_record / newsignalcomp->edfhdr->data_record_duration) / 2.0)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "The frequency of the filter(s) must be less than: samplerate / 2"); messagewindow.exec(); free(newsignalcomp); xml_close(xml_hdl); return; } if(type == 0) { sprintf(spec_str, "HpBu1/%f", frequency); } if(type == 1) { sprintf(spec_str, "LpBu1/%f", frequency); } filter_spec = spec_str; err = fid_parse(((double)(newsignalcomp->edfhdr->edfparam[newsignalcomp->edfsignal[0]].smp_per_record)) / newsignalcomp->edfhdr->data_record_duration, &filter_spec, &newsignalcomp->fidfilter[filters_read]); if(err != NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", err); messagewindow.exec(); free(err); free(newsignalcomp); xml_close(xml_hdl); return; } newsignalcomp->fid_run[filters_read] = fid_run_new(newsignalcomp->fidfilter[filters_read], &newsignalcomp->fidfuncp[filters_read]); newsignalcomp->fidbuf[filters_read] = fid_run_newbuf(newsignalcomp->fid_run[filters_read]); newsignalcomp->fidbuf2[filters_read] = fid_run_newbuf(newsignalcomp->fid_run[filters_read]); newsignalcomp->fidfilter_freq[filters_read] = frequency; newsignalcomp->fidfilter_freq2[filters_read] = frequency * 1.12; newsignalcomp->fidfilter_ripple[filters_read] = -1.0; newsignalcomp->fidfilter_order[filters_read] = 1; newsignalcomp->fidfilter_type[filters_read] = type; newsignalcomp->fidfilter_model[filters_read] = 0; newsignalcomp->fidfilter_setup[filters_read] = 1; newsignalcomp->fidfilter_cnt = filters_read + 1; xml_go_up(xml_hdl); xml_go_up(xml_hdl); } for(filters_read=0; filters_read 1) || (size < 2) || (size > 10000)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There seems to be an error in this montage file. (ravg_filter values)"); messagewindow.exec(); free(newsignalcomp); xml_close(xml_hdl); return; } newsignalcomp->ravg_filter[filters_read] = create_ravg_filter(type, size); if(newsignalcomp->ravg_filter[filters_read] == NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "A memory allocation error occurred when creating an ravg filter."); messagewindow.exec(); free(newsignalcomp); xml_close(xml_hdl); return; } newsignalcomp->ravg_filter_size[filters_read] = size; newsignalcomp->ravg_filter_type[filters_read] = type; newsignalcomp->ravg_filter_cnt = filters_read + 1; xml_go_up(xml_hdl); xml_go_up(xml_hdl); } for(filters_read=0; filters_read 2) || (order < 1) || (order > 100) || (type < 0) || (type > 4) || (ripple < (-6.0)) || (ripple > (-0.1)) || (frequency < 0.0001) || (frequency2 < 0.0001)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There seems to be an error in this montage file. (fidfilter values)"); messagewindow.exec(); free(newsignalcomp); xml_close(xml_hdl); return; } if(frequency >= ((newsignalcomp->edfhdr->edfparam[newsignalcomp->edfsignal[0]].smp_per_record / newsignalcomp->edfhdr->data_record_duration) / 2.0)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "The frequency of the filter(s) must be less than: samplerate / 2"); messagewindow.exec(); free(newsignalcomp); xml_close(xml_hdl); return; } if(type > 2) { if(frequency2 >= ((newsignalcomp->edfhdr->edfparam[newsignalcomp->edfsignal[0]].smp_per_record / newsignalcomp->edfhdr->data_record_duration) / 2.0)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "The frequency of the filter(s) must be less than: samplerate / 2"); messagewindow.exec(); free(newsignalcomp); xml_close(xml_hdl); return; } } if((type == 0) || (type == 1)) { if(order > 8) { order = 8; } } if(type == 0) { if(model == 0) { sprintf(spec_str, "HpBu%i/%f", order, frequency); } if(model == 1) { sprintf(spec_str, "HpCh%i/%f/%f", order, ripple, frequency); } if(model == 2) { sprintf(spec_str, "HpBe%i/%f", order, frequency); } } if(type == 1) { if(model == 0) { sprintf(spec_str, "LpBu%i/%f", order, frequency); } if(model == 1) { sprintf(spec_str, "LpCh%i/%f/%f", order, ripple, frequency); } if(model == 2) { sprintf(spec_str, "LpBe%i/%f", order, frequency); } } if(type == 2) { if(order > 100) { order = 100; } if(order < 3) { order = 3; } if(model == 0) { sprintf(spec_str, "BsRe/%i/%f", order, frequency); } } if((type == 3) || (type == 4)) { if(order < 2) { order = 2; } if(order % 2) { order++; } if(order > 16) { order = 16; } } if(type == 3) { if(model == 0) { sprintf(spec_str, "BpBu%i/%f-%f", order, frequency, frequency2); } if(model == 1) { sprintf(spec_str, "BpCh%i/%f/%f-%f", order, ripple, frequency, frequency2); } if(model == 2) { sprintf(spec_str, "BpBe%i/%f-%f", order, frequency, frequency2); } } if(type == 4) { if(model == 0) { sprintf(spec_str, "BsBu%i/%f-%f", order, frequency, frequency2); } if(model == 1) { sprintf(spec_str, "BsCh%i/%f/%f-%f", order, ripple, frequency, frequency2); } if(model == 2) { sprintf(spec_str, "BsBe%i/%f-%f", order, frequency, frequency2); } } filter_spec = spec_str; err = fid_parse(((double)(newsignalcomp->edfhdr->edfparam[newsignalcomp->edfsignal[0]].smp_per_record)) / newsignalcomp->edfhdr->data_record_duration, &filter_spec, &newsignalcomp->fidfilter[filters_read]); if(err != NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", err); messagewindow.exec(); free(err); free(newsignalcomp); xml_close(xml_hdl); return; } newsignalcomp->fid_run[filters_read] = fid_run_new(newsignalcomp->fidfilter[filters_read], &newsignalcomp->fidfuncp[filters_read]); newsignalcomp->fidbuf[filters_read] = fid_run_newbuf(newsignalcomp->fid_run[filters_read]); newsignalcomp->fidbuf2[filters_read] = fid_run_newbuf(newsignalcomp->fid_run[filters_read]); newsignalcomp->fidfilter_freq[filters_read] = frequency; newsignalcomp->fidfilter_freq2[filters_read] = frequency2; newsignalcomp->fidfilter_ripple[filters_read] = ripple; newsignalcomp->fidfilter_order[filters_read] = order; newsignalcomp->fidfilter_type[filters_read] = type; newsignalcomp->fidfilter_model[filters_read] = model; newsignalcomp->fidfilter_setup[filters_read] = 1; newsignalcomp->fidfilter_cnt = filters_read + 1; xml_go_up(xml_hdl); xml_go_up(xml_hdl); } if(!xml_goto_nth_element_inside(xml_hdl, "ecg_filter", 0)) { if(xml_goto_nth_element_inside(xml_hdl, "type", 0)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There seems to be an error in this montage file."); messagewindow.exec(); free(newsignalcomp); xml_close(xml_hdl); return; } result = xml_get_content_of_element(xml_hdl); type = atoi(result); free(result); if(type == 1) { newsignalcomp->ecg_filter = create_ecg_filter(newsignalcomp->edfhdr->edfparam[newsignalcomp->edfsignal[0]].smp_per_record / newsignalcomp->edfhdr->data_record_duration, newsignalcomp->edfhdr->edfparam[newsignalcomp->edfsignal[0]].bitvalue, mainwindow->powerlinefreq); if(newsignalcomp->ecg_filter == NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "A memory allocation error occurred when creating an ECG filter."); messagewindow.exec(); free(newsignalcomp); xml_close(xml_hdl); return; } strcpy(newsignalcomp->signallabel_bu, newsignalcomp->signallabel); newsignalcomp->signallabellen_bu = newsignalcomp->signallabellen; strcpy(newsignalcomp->signallabel, "HR"); newsignalcomp->signallabellen = strlen(newsignalcomp->signallabel); strcpy(newsignalcomp->physdimension_bu, newsignalcomp->physdimension); strcpy(newsignalcomp->physdimension, "bpm"); } xml_go_up(xml_hdl); xml_go_up(xml_hdl); } if(newsignalcomp->ecg_filter == NULL) { if(!xml_goto_nth_element_inside(xml_hdl, "zratio_filter", 0)) { if(xml_goto_nth_element_inside(xml_hdl, "type", 0)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There seems to be an error in this montage file."); messagewindow.exec(); free(newsignalcomp); xml_close(xml_hdl); return; } result = xml_get_content_of_element(xml_hdl); type = atoi(result); free(result); xml_go_up(xml_hdl); if(type == 1) { if(xml_goto_nth_element_inside(xml_hdl, "crossoverfreq", 0)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There seems to be an error in this montage file."); messagewindow.exec(); free(newsignalcomp); xml_close(xml_hdl); return; } result = xml_get_content_of_element(xml_hdl); newsignalcomp->zratio_crossoverfreq = atof(result); free(result); if((newsignalcomp->zratio_crossoverfreq < 5.0) || (newsignalcomp->zratio_crossoverfreq > 9.5)) { newsignalcomp->zratio_crossoverfreq = 7.5; } newsignalcomp->zratio_filter = create_zratio_filter(newsignalcomp->edfhdr->edfparam[newsignalcomp->edfsignal[0]].smp_per_record, newsignalcomp->edfhdr->long_data_record_duration, newsignalcomp->zratio_crossoverfreq, newsignalcomp->edfhdr->edfparam[newsignalcomp->edfsignal[0]].bitvalue); if(newsignalcomp->zratio_filter == NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "A memory allocation error occurred when creating a Z-ratio filter."); messagewindow.exec(); free(newsignalcomp); xml_close(xml_hdl); return; } strcpy(newsignalcomp->signallabel_bu, newsignalcomp->signallabel); newsignalcomp->signallabellen_bu = newsignalcomp->signallabellen; strcpy(newsignalcomp->signallabel, "Z-ratio "); strcat(newsignalcomp->signallabel, newsignalcomp->signallabel_bu); newsignalcomp->signallabellen = strlen(newsignalcomp->signallabel); strcpy(newsignalcomp->physdimension_bu, newsignalcomp->physdimension); strcpy(newsignalcomp->physdimension, ""); xml_go_up(xml_hdl); } xml_go_up(xml_hdl); } } if(f_ruler_cnt == 0) { if(!xml_goto_nth_element_inside(xml_hdl, "floating_ruler", 0)) { if(xml_goto_nth_element_inside(xml_hdl, "hasruler", 0)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There seems to be an error in this montage file."); messagewindow.exec(); free(newsignalcomp); xml_close(xml_hdl); return; } result = xml_get_content_of_element(xml_hdl); tmp = atoi(result); free(result); xml_go_up(xml_hdl); if(tmp == 1) { f_ruler_cnt = 1; mainwindow->maincurve->ruler_x_position = 200; mainwindow->maincurve->ruler_y_position = 200; mainwindow->maincurve->floating_ruler_value = 0; if(!xml_goto_nth_element_inside(xml_hdl, "ruler_x_position", 0)) { result = xml_get_content_of_element(xml_hdl); tmp = atoi(result); free(result); if((tmp >= 0) && (tmp < 5000)) { mainwindow->maincurve->ruler_x_position = tmp; } xml_go_up(xml_hdl); } if(!xml_goto_nth_element_inside(xml_hdl, "ruler_y_position", 0)) { result = xml_get_content_of_element(xml_hdl); tmp = atoi(result); free(result); if((tmp >= 0) && (tmp < 5000)) { mainwindow->maincurve->ruler_y_position = tmp; } xml_go_up(xml_hdl); } if(!xml_goto_nth_element_inside(xml_hdl, "floating_ruler_value", 0)) { result = xml_get_content_of_element(xml_hdl); tmp = atoi(result); free(result); if((tmp >= 0) && (tmp < 2)) { mainwindow->maincurve->floating_ruler_value = tmp; } xml_go_up(xml_hdl); } newsignalcomp->hasruler = 1; } xml_go_up(xml_hdl); } } mainwindow->signalcomp[mainwindow->signalcomps] = newsignalcomp; mainwindow->signalcomps++; signalcomps_read++; } xml_goto_root(xml_hdl); if(!(xml_goto_nth_element_inside(xml_hdl, "pagetime", 0))) { result = xml_get_content_of_element(xml_hdl); mainwindow->pagetime = atoll(result); if(mainwindow->pagetime < 10000LL) { mainwindow->pagetime = 10000LL; } free(result); } xml_close(xml_hdl); if(LoadMontageDialog!=NULL) LoadMontageDialog->close(); mainwindow->setMainwindowTitle(mainwindow->edfheaderlist[mainwindow->sel_viewtime]); if(mainwindow->files_open == 1) { strcpy(&mainwindow->recent_file_mtg_path[0][0], mtg_path); } mainwindow->timescale_doubler = round_125_cat(mainwindow->pagetime); for(i=0; i<3; i++) { amp_cat[i] = 0; } for(i=0; isignalcomps; i++) { tmp = round_125_cat(mainwindow->signalcomp[i]->voltpercm); switch(tmp) { case 10 : amp_cat[0]++; break; case 20 : amp_cat[1]++; break; case 50 : amp_cat[2]++; break; } } mainwindow->amplitude_doubler = 10; if((amp_cat[1] > amp_cat[0]) && (amp_cat[1] >= amp_cat[2])) { mainwindow->amplitude_doubler = 20; } if((amp_cat[2] > amp_cat[0]) && (amp_cat[2] > amp_cat[1])) { mainwindow->amplitude_doubler = 50; } if(f_ruler_cnt == 1) { mainwindow->maincurve->ruler_active = 1; } mainwindow->setup_viewbuf(); } void UI_LoadMontagewindow::strip_types_from_label(char *label) { int i, len; len = strlen(label); if(len<16) { return; } if((!(strncmp(label, "EEG ", 4))) ||(!(strncmp(label, "ECG ", 4))) ||(!(strncmp(label, "EOG ", 4))) ||(!(strncmp(label, "ERG ", 4))) ||(!(strncmp(label, "EMG ", 4))) ||(!(strncmp(label, "MEG ", 4))) ||(!(strncmp(label, "MCG ", 4)))) { if(label[4]!=' ') { for(i=0; i<(len-4); i++) { label[i] = label[i+4]; } for(; i #include "filter.h" #include "third_party/fidlib/fidlib.h" #include "ravg_filter.h" #include "ecg_filter.h" #include "z_ratio_filter.h" struct edfparamblock{ char label[17]; char transducer[81]; char physdimension[9]; double phys_min; double phys_max; int dig_min; int dig_max; char prefilter[81]; int smp_per_record; char reserved[33]; double offset; int buf_offset; double bitvalue; int annotation; }; struct edfhdrblock{ FILE *file_hdl; int file_num; char version[32]; char filename[MAX_PATH_LENGTH]; char patient[81]; char recording[81]; char plus_patientcode[81]; char plus_gender[16]; char plus_birthdate[16]; char plus_patient_name[81]; char plus_patient_additional[81]; char plus_startdate[16]; char plus_admincode[81]; char plus_technician[81]; char plus_equipment[81]; char plus_recording_additional[81]; long long l_starttime; long long utc_starttime; char reserved[45]; int hdrsize; int edfsignals; long long datarecords; int recordsize; int annot_ch[256]; int nr_annot_chns; int edf; int edfplus; int bdf; int bdfplus; int discontinuous; int genuine_nk; int nk_triggers_read; int genuine_biosemi; double data_record_duration; long long long_data_record_duration; long long viewtime; long long starttime_offset; long long prefiltertime; int annots_not_read; struct edfparamblock *edfparam; }; struct signalcompblock{ int filenum; struct edfhdrblock *edfhdr; int num_of_signals; int viewbufsize; int viewbufoffset; long long records_in_viewbuf; long long samples_in_viewbuf; long long samples_on_screen; long long sample_start; long long sample_stop; int timeoffset; int sample_timeoffset; int pixels_shift; double sample_timeoffset_part; double sample_pixel_ratio; int edfsignal[MAXSIGNALS]; int factor[MAXSIGNALS]; int polarity; double sensitivity[MAXSIGNALS]; int oldvalue; long long oldsmplnr; long long file_duration; char signallabel[512]; char alias[17]; int signallabellen; char signallabel_bu[512]; int signallabellen_bu; int hascursor1; int hascursor2; int hasoffsettracking; int hasgaintracking; int hasruler; double screen_offset; double voltpercm; char physdimension[9]; char physdimension_bu[9]; int color; int filter_cnt; int samples_in_prefilterbuf; long long prefilter_starttime; int prefilter_reset_sample; double filterpreset_a[MAXFILTERS]; double filterpreset_b[MAXFILTERS]; struct filter_settings *filter[MAXFILTERS]; int max_dig_value; int min_dig_value; int fidfilter_cnt; int fidfilter_type[MAXFILTERS]; double fidfilter_freq[MAXFILTERS]; double fidfilter_freq2[MAXFILTERS]; double fidfilter_ripple[MAXFILTERS]; int fidfilter_order[MAXFILTERS]; int fidfilter_model[MAXFILTERS]; FidFilter *fidfilter[MAXFILTERS]; FidRun *fid_run[MAXFILTERS]; FidFunc *fidfuncp[MAXFILTERS]; void *fidbuf[MAXFILTERS]; void *fidbuf2[MAXFILTERS]; int fidfilter_setup[MAXFILTERS]; int stat_cnt; int stat_zero_crossing_cnt; double stat_sum; double stat_sum_sqr; double stat_sum_rectified; int ravg_filter_cnt; int ravg_filter_type[MAXFILTERS]; int ravg_filter_size[MAXFILTERS]; int ravg_filter_setup[MAXFILTERS]; struct ravg_filter_settings *ravg_filter[MAXFILTERS]; struct ecg_filter_settings *ecg_filter; struct zratio_filter_settings *zratio_filter; double zratio_crossoverfreq; int spectr_dialog[MAXSPECTRUMDIALOGS]; int avg_dialog[MAXAVERAGECURVEDIALOGS]; int zscoredialog[MAXZSCOREDIALOGS]; }; struct zoomhistoryblock{ int pntr; int history_size_tail; int history_size_front; long long viewtime[64][MAXFILES]; long long pagetime[64]; double voltpercm[64][MAXSIGNALS]; double sensitivity[64][MAXSIGNALS][MAXSIGNALS]; double screen_offset[64][MAXSIGNALS]; }; struct annotationblock{ int file_num; long long onset; char duration[16]; char annotation[MAX_ANNOTATION_LEN + 1]; struct annotationblock *former_annotation; struct annotationblock *next_annotation; int modified; int x_pos; int selected; int jump; int hided; int hided_in_list; unsigned int ident; }; struct active_markersblock{ int file_num; struct annotationblock *list[MAX_ACTIVE_ANNOT_MARKERS]; int count; int selected; }; struct graphicLineStruct{ int x1; int y1; int x2; int y2; }; struct graphicBufStruct{ struct graphicLineStruct graphicLine[MAXSIGNALS]; }; struct crossHairStruct{ int color; int file_num; int active; int moving; int position; int x_position; int y_position; int y_value; double value; long long time; long long time_relative; }; #endif edfbrowser_153_source/PaxHeaders.2978/show_edf_hdr.cpp0000644000175000001440000000013212251654530021306 xustar000000000000000030 mtime=1386699096.479032511 30 atime=1386699096.479032511 30 ctime=1386699096.479032511 edfbrowser_153_source/show_edf_hdr.cpp0000644000175000001440000003511012251654530021037 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "show_edf_hdr.h" UI_EDFhdrwindow::UI_EDFhdrwindow(QWidget *w_parent) { int i; edfplus_layout = 0; mainwindow = (UI_Mainwindow *)w_parent; EDFhdrDialog = new QDialog; EDFhdrDialog->setMinimumSize(QSize(690, 480)); EDFhdrDialog->setMaximumSize(QSize(690, 480)); EDFhdrDialog->setWindowTitle("File Info"); EDFhdrDialog->setModal(TRUE); EDFhdrDialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); filelist = new QListWidget(EDFhdrDialog); filelist->setGeometry(QRect(10, 10, 670, 75)); for(i=0; ifiles_open; i++) { new QListWidgetItem(QString::fromLocal8Bit(mainwindow->edfheaderlist[i]->filename), filelist); } label1 = new QLabel(EDFhdrDialog); label1->setGeometry(QRect(10, 120, 80, 25)); label1->setText("Subject"); label1a = new SpecialButton(EDFhdrDialog); label1a->setGeometry(QRect(100, 120, 580, 25)); label1a->setColor(Qt::white); label2 = new QLabel(EDFhdrDialog); label2->setGeometry(QRect(10, 155, 80, 25)); label2->setText("Recording"); label2a = new SpecialButton(EDFhdrDialog); label2a->setGeometry(QRect(100, 155, 580, 25)); label2a->setColor(Qt::white); label3 = new QLabel(EDFhdrDialog); label3->setGeometry(QRect(10, 190, 80, 25)); label3->setText("Start"); label3a = new SpecialButton(EDFhdrDialog); label3a->setGeometry(QRect(100, 190, 180, 25)); label3a->setColor(Qt::white); label4 = new QLabel(EDFhdrDialog); label4->setGeometry(QRect(410, 190, 80, 25)); label4->setText("Duration"); label4a = new SpecialButton(EDFhdrDialog); label4a->setGeometry(QRect(500, 190, 180, 25)); label4a->setColor(Qt::white); label5 = new QLabel(EDFhdrDialog); label5->setGeometry(QRect(10, 225, 80, 25)); label5->setText("Reserved"); label5a = new SpecialButton(EDFhdrDialog); label5a->setGeometry(QRect(100, 225, 350, 25)); label5a->setColor(Qt::white); label6 = new QLabel(EDFhdrDialog); label6->setGeometry(QRect(10, 190, 130, 25)); label6->setText("Birthdate"); label6->setVisible(FALSE); label6a = new SpecialButton(EDFhdrDialog); label6a->setGeometry(QRect(150, 190, 530, 25)); label6a->setColor(Qt::white); label6a->setVisible(FALSE); label7 = new QLabel(EDFhdrDialog); label7->setGeometry(QRect(10, 225, 130, 25)); label7->setText("Subject name"); label7->setVisible(FALSE); label7a = new SpecialButton(EDFhdrDialog); label7a->setGeometry(QRect(150, 225, 530, 25)); label7a->setColor(Qt::white); label7a->setVisible(FALSE); label8 = new QLabel(EDFhdrDialog); label8->setGeometry(QRect(10, 260, 130, 25)); label8->setText("Additional info"); label8->setVisible(FALSE); label8a = new SpecialButton(EDFhdrDialog); label8a->setGeometry(QRect(150, 260, 530, 25)); label8a->setColor(Qt::white); label8a->setVisible(FALSE); label9 = new QLabel(EDFhdrDialog); label9->setGeometry(QRect(10, 290, 130, 25)); label9->setText("Startdate"); label9->setVisible(FALSE); label9a = new SpecialButton(EDFhdrDialog); label9a->setGeometry(QRect(150, 290, 530, 25)); label9a->setColor(Qt::white); label9a->setVisible(FALSE); label10 = new QLabel(EDFhdrDialog); label10->setGeometry(QRect(10, 325, 130, 25)); label10->setText("Administr. code"); label10->setVisible(FALSE); label10a = new SpecialButton(EDFhdrDialog); label10a->setGeometry(QRect(150, 325, 530, 25)); label10a->setColor(Qt::white); label10a->setVisible(FALSE); label11 = new QLabel(EDFhdrDialog); label11->setGeometry(QRect(10, 360, 130, 25)); label11->setText("Technician"); label11->setVisible(FALSE); label11a = new SpecialButton(EDFhdrDialog); label11a->setGeometry(QRect(150, 360, 530, 25)); label11a->setColor(Qt::white); label11a->setVisible(FALSE); label12 = new QLabel(EDFhdrDialog); label12->setGeometry(QRect(10, 395, 130, 25)); label12->setText("Device"); label12->setVisible(FALSE); label12a = new SpecialButton(EDFhdrDialog); label12a->setGeometry(QRect(150, 395, 530, 25)); label12a->setColor(Qt::white); label12a->setVisible(FALSE); label13 = new QLabel(EDFhdrDialog); label13->setGeometry(QRect(10, 430, 130, 25)); label13->setText("Additional info"); label13->setVisible(FALSE); label13a = new SpecialButton(EDFhdrDialog); label13a->setGeometry(QRect(150, 430, 530, 25)); label13a->setColor(Qt::white); label13a->setVisible(FALSE); label20 = new QLabel(EDFhdrDialog); label20->setGeometry(QRect(10, 260, 130, 25)); label20->setText("Datarecord duration"); label20a = new SpecialButton(EDFhdrDialog); label20a->setGeometry(QRect(150, 260, 100, 25)); label20a->setColor(Qt::white); label21 = new QLabel(EDFhdrDialog); label21->setGeometry(QRect(410, 260, 80, 25)); label21->setText("Version"); label21a = new SpecialButton(EDFhdrDialog); label21a->setGeometry(QRect(500, 260, 180, 25)); label21a->setColor(Qt::white); signallist = new QTableWidget(EDFhdrDialog); signallist->setGeometry(QRect(10, 295, 670, 100)); signallist->setSelectionMode(QAbstractItemView::NoSelection); signallist->setEditTriggers(QAbstractItemView::NoEditTriggers); pushButton1 = new QPushButton(EDFhdrDialog); pushButton1->setGeometry(QRect(580, 445, 100, 25)); pushButton1->setText("Close"); QObject::connect(pushButton1, SIGNAL(clicked()), EDFhdrDialog, SLOT(close())); QObject::connect(filelist, SIGNAL(currentRowChanged(int)), this, SLOT(show_params(int))); filelist->setCurrentRow(mainwindow->files_open - 1); EDFhdrDialog->exec(); } void UI_EDFhdrwindow::show_params(int row) { int i, signal_cnt; char str[512]; long long file_duration; struct date_time_struct date_time; if(row<0) return; if(mainwindow->edfheaderlist[row]->edfplus || mainwindow->edfheaderlist[row]->bdfplus) { edfplus_layout = 1; EDFhdrDialog->setMinimumSize(QSize(690, 765)); EDFhdrDialog->setMaximumSize(QSize(690, 765)); pushButton1->setGeometry(QRect(580, 730, 100, 25)); signallist->setGeometry(QRect(10, 580, 670, 100)); label20a->setGeometry(QRect(150, 545, 100, 25)); label20->setGeometry(QRect(10, 545, 130, 25)); label21->setGeometry(QRect(410, 545, 80, 25)); label21a->setGeometry(QRect(500, 545, 180, 25)); label5a->setGeometry(QRect(150, 500, 350, 25)); label5->setGeometry(QRect(10, 500, 80, 25)); label4a->setGeometry(QRect(500, 465, 180, 25)); label4->setGeometry(QRect(410, 465, 80, 25)); label3a->setGeometry(QRect(150, 465, 180, 25)); label3->setGeometry(QRect(10, 465, 80, 25)); label1a->setGeometry(QRect(150, 120, 530, 25)); label1a->setText(mainwindow->edfheaderlist[row]->plus_patientcode); label1->setGeometry(QRect(10, 120, 130, 25)); label1->setText("Subject code"); label2a->setGeometry(QRect(150, 155, 530, 25)); label2a->setText(mainwindow->edfheaderlist[row]->plus_gender); label2->setGeometry(QRect(10, 155, 130, 25)); label2->setText("Sex"); label6->setVisible(TRUE); label6a->setVisible(TRUE); label6a->setText(mainwindow->edfheaderlist[row]->plus_birthdate); label7->setVisible(TRUE); label7a->setVisible(TRUE); label7a->setText(mainwindow->edfheaderlist[row]->plus_patient_name); label8->setVisible(TRUE); label8a->setVisible(TRUE); label8a->setText(mainwindow->edfheaderlist[row]->plus_patient_additional); label9->setVisible(TRUE); label9a->setVisible(TRUE); label9a->setText(mainwindow->edfheaderlist[row]->plus_startdate); label10->setVisible(TRUE); label10a->setVisible(TRUE); label10a->setText(mainwindow->edfheaderlist[row]->plus_admincode); label11->setVisible(TRUE); label11a->setVisible(TRUE); label11a->setText(mainwindow->edfheaderlist[row]->plus_technician); label12->setVisible(TRUE); label12a->setVisible(TRUE); label12a->setText(mainwindow->edfheaderlist[row]->plus_equipment); label13->setVisible(TRUE); label13a->setVisible(TRUE); label13a->setText(mainwindow->edfheaderlist[row]->plus_recording_additional); } else { label6->setVisible(FALSE); label6a->setVisible(FALSE); label7->setVisible(FALSE); label7a->setVisible(FALSE); label8->setVisible(FALSE); label8a->setVisible(FALSE); label9->setVisible(FALSE); label9a->setVisible(FALSE); label10->setVisible(FALSE); label10a->setVisible(FALSE); label11->setVisible(FALSE); label11a->setVisible(FALSE); label12->setVisible(FALSE); label12a->setVisible(FALSE); label13->setVisible(FALSE); label13a->setVisible(FALSE); EDFhdrDialog->setMinimumSize(QSize(690, 480)); EDFhdrDialog->setMaximumSize(QSize(690, 480)); label1->setGeometry(QRect(10, 120, 80, 25)); label1->setText("Subject"); label1a->setGeometry(QRect(100, 120, 580, 25)); label1a->setText(mainwindow->edfheaderlist[row]->patient); label2->setGeometry(QRect(10, 155, 80, 25)); label2->setText("Recording"); label2a->setGeometry(QRect(100, 155, 580, 25)); label2a->setText(mainwindow->edfheaderlist[row]->recording); label3a->setGeometry(QRect(100, 190, 180, 25)); label3->setGeometry(QRect(10, 190, 80, 25)); label4a->setGeometry(QRect(500, 190, 180, 25)); label4->setGeometry(QRect(410, 190, 80, 25)); label5a->setGeometry(QRect(100, 225, 350, 25)); label5->setGeometry(QRect(10, 225, 80, 25)); label20->setGeometry(QRect(10, 260, 130, 25)); label20a->setGeometry(QRect(150, 260, 100, 25)); label21->setGeometry(QRect(410, 260, 80, 25)); label21a->setGeometry(QRect(500, 260, 180, 25)); signallist->setGeometry(QRect(10, 295, 670, 100)); pushButton1->setGeometry(QRect(580, 445, 100, 25)); } utc_to_date_time(mainwindow->edfheaderlist[row]->utc_starttime, &date_time); date_time.month_str[0] += 32; date_time.month_str[1] += 32; date_time.month_str[2] += 32; snprintf(str, 400, "%i %s %i %2i:%02i:%02i", date_time.day, date_time.month_str, date_time.year, date_time.hour, date_time.minute, date_time.second); if(mainwindow->edfheaderlist[row]->starttime_offset != 0LL) { #ifdef Q_WS_WIN snprintf(str + strlen(str), 100, ".%07I64d", mainwindow->edfheaderlist[row]->starttime_offset); #else snprintf(str + strlen(str), 100, ".%07lli", mainwindow->edfheaderlist[row]->starttime_offset); #endif remove_trailing_zeros(str); } label3a->setText(str); file_duration = mainwindow->edfheaderlist[row]->long_data_record_duration * mainwindow->edfheaderlist[row]->datarecords; snprintf(str, 512, "%2i:%02i:%02i", (int)((file_duration / TIME_DIMENSION)/ 3600LL), (int)(((file_duration / TIME_DIMENSION) % 3600LL) / 60LL), (int)((file_duration / TIME_DIMENSION) % 60LL)); label4a->setText(str); label5a->setText(mainwindow->edfheaderlist[row]->reserved); snprintf(str, 512, "%.12f", mainwindow->edfheaderlist[row]->data_record_duration); remove_trailing_zeros(str); label20a->setText(str); label21a->setText(mainwindow->edfheaderlist[row]->version); signal_cnt = mainwindow->edfheaderlist[row]->edfsignals; signallist->setColumnCount(10); signallist->setRowCount(signal_cnt); signallist->setSelectionMode(QAbstractItemView::NoSelection); signallist->setColumnWidth(0, 180); signallist->setColumnWidth(1, 120); signallist->setColumnWidth(2, 120); signallist->setColumnWidth(3, 120); signallist->setColumnWidth(4, 120); signallist->setColumnWidth(5, 120); signallist->setColumnWidth(6, 120); signallist->setColumnWidth(7, 120); signallist->setColumnWidth(8, 520); signallist->setColumnWidth(9, 520); QStringList horizontallabels; horizontallabels += "Label"; horizontallabels += "Samplefrequency"; horizontallabels += "Physical maximum"; horizontallabels += "Physical minimum"; horizontallabels += "Physical dimension"; horizontallabels += "Digital maximum"; horizontallabels += "Digital minimum"; horizontallabels += "Samples per record"; horizontallabels += "Prefilter"; horizontallabels += "Transducer"; signallist->setHorizontalHeaderLabels(horizontallabels); for(i=0; isetRowHeight(i, 20); signallist->setCellWidget(i, 0, new QLabel(mainwindow->edfheaderlist[row]->edfparam[i].label)); snprintf(str, 512, "%f", (double)mainwindow->edfheaderlist[row]->edfparam[i].smp_per_record / mainwindow->edfheaderlist[row]->data_record_duration); strcat(str, " Hz"); remove_trailing_zeros(str); signallist->setCellWidget(i, 1, new QLabel(str)); snprintf(str, 512, "%+f", mainwindow->edfheaderlist[row]->edfparam[i].phys_max); remove_trailing_zeros(str); signallist->setCellWidget(i, 2, new QLabel(str)); snprintf(str, 512, "%+f", mainwindow->edfheaderlist[row]->edfparam[i].phys_min); remove_trailing_zeros(str); signallist->setCellWidget(i, 3, new QLabel(str)); signallist->setCellWidget(i, 4, new QLabel(mainwindow->edfheaderlist[row]->edfparam[i].physdimension)); snprintf(str, 512, "%+i", mainwindow->edfheaderlist[row]->edfparam[i].dig_max); signallist->setCellWidget(i, 5, new QLabel(str)); snprintf(str, 512, "%+i", mainwindow->edfheaderlist[row]->edfparam[i].dig_min); signallist->setCellWidget(i, 6, new QLabel(str)); snprintf(str, 512, "%i", mainwindow->edfheaderlist[row]->edfparam[i].smp_per_record); signallist->setCellWidget(i, 7, new QLabel(str)); signallist->setCellWidget(i, 8, new QLabel(mainwindow->edfheaderlist[row]->edfparam[i].prefilter)); signallist->setCellWidget(i, 9, new QLabel(mainwindow->edfheaderlist[row]->edfparam[i].transducer)); } } edfbrowser_153_source/PaxHeaders.2978/z_score_dialog.h0000644000175000001440000000013212251654530021303 xustar000000000000000030 mtime=1386699096.468032569 30 atime=1386699096.468032569 30 ctime=1386699096.468032569 edfbrowser_153_source/z_score_dialog.h0000644000175000001440000000726412251654530021045 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef ZSCORE_FORM1_H #define ZSCORE_FORM1_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "mainwindow.h" #include "edf_annot_list.h" #include "utils.h" #include "filteredblockread.h" #include "signalcurve.h" #include "annotations_dock.h" #include "filter.h" #include "ravg_filter.h" #include "third_party/kiss_fft/kiss_fftr.h" class UI_Mainwindow; class UI_ZScoreWindow : public QObject { Q_OBJECT public: UI_ZScoreWindow(QWidget *, UI_ZScoreWindow **, int, int); ~UI_ZScoreWindow(); UI_Mainwindow *mainwindow; QDialog *zscore_dialog; private: QHBoxLayout *hlayout1, *hlayout2, *hlayout3, *hlayout4, *hlayout5; QVBoxLayout *vlayout2, *vlayout3; QLabel *crossoverbinLabel, *thresholdLabel, *pagelenLabel, *hysteresisLabel; // *errordetectionLabel; QPushButton *CloseButton, *StartButton, *get_annotButton, *defaultButton, *jumpButton, *addTraceButton; QSpinBox *pagelenSpinbox; // *errordetectionSpinbox; QDoubleSpinBox *thresholdSpinbox, *crossoverSpinbox, *hysteresisSpinbox; QRadioButton *epochRadioButton, *pageRadioButton, *wakesleepRadioButton; SignalCurve *curve1; UI_ZScoreWindow **zscoredialog; QAction *shift_page_right_Act, *shift_page_left_Act; int signalnr, zscore_page_len, avg_majority, epoch_cntr, zscore_pages, zscore_wake, *zscore_sleepstage_buf, *zscore_error_buf, plot_type, zscore_dialog_is_destroyed, zscore_dialognumber, zscore_error_detection; double *zscore_epoch_buf, *zscore_page_buf, crossoverfreq, z_threshold, z_hysteresis; private slots: void startButtonClicked(); void get_annotationsButtonClicked(); void jumpButtonClicked(); void ZscoreDialogDestroyed(QObject *); void RadioButtonsClicked(bool); void defaultButtonClicked(); void markersMoved(); void addTraceButtonClicked(); void shift_page_right(); void shift_page_left(); }; #endif // ZSCORE_FORM1_H edfbrowser_153_source/PaxHeaders.2978/edf_compat.h0000644000175000001440000000013212251654530020421 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/edf_compat.h0000644000175000001440000000410412251654530020151 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef EDFCOMPATFORM1_H #define EDFCOMPATFORM1_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "mainwindow.h" #include "popup_messagewindow.h" class UI_Mainwindow; class UI_EDFCompatwindow : public QObject { Q_OBJECT public: UI_EDFCompatwindow(QWidget *parent); UI_Mainwindow *mainwindow; private: QDialog *EDFCompatDialog; QListWidget *filelist; QPushButton *CloseButton, *CheckButton; int is_duration_number(char *); int is_onset_number(char *); int is_integer_number(char *); int is_number(char *); private slots: void CheckButtonClicked(); }; #endif // EDFCOMPATFORM1_H edfbrowser_153_source/PaxHeaders.2978/bdf2edf.h0000644000175000001440000000012712251654530017620 xustar000000000000000029 mtime=1386699096.46603258 29 atime=1386699096.46603258 29 ctime=1386699096.46603258 edfbrowser_153_source/bdf2edf.h0000644000175000001440000000554712251654530017360 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef UI_BDF2EDFFORM_H #define UI_BDF2EDFFORM_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "mainwindow.h" #include "check_edf_file.h" #include "popup_messagewindow.h" #include "filter.h" #include "utils.h" class UI_Mainwindow; class UI_BDF2EDFwindow : public QObject { Q_OBJECT public: UI_BDF2EDFwindow(QWidget *parent); UI_Mainwindow *mainwindow; private: QLabel *label1, *label2, *label3; QPushButton *pushButton1, *pushButton2, *pushButton3, *pushButton4, *pushButton5; QDoubleSpinBox *spinBox1, *spinBox2; QTableWidget *SignalsTablewidget; QDialog *myobjectDialog; int signalslist[MAXSIGNALS], annotlist[MAXSIGNALS]; char inputpath[MAX_PATH_LENGTH], outputpath[MAX_PATH_LENGTH], *recent_opendir, *recent_savedir; double dividerlist[MAXSIGNALS]; FILE *inputfile, *outputfile; struct edfhdrblock *edfhdr; struct filter_settings *filterlist[MAXSIGNALS]; void showpopupmessage(const char *, const char *); private slots: void SelectFileButton(); void StartConversion(); void spinbox1_changed(double); void spinbox2_changed(double); void Select_all_signals(); void Deselect_all_signals(); void free_edfheader(); }; #endif edfbrowser_153_source/PaxHeaders.2978/edflib.c0000644000175000001440000000013212251654530017540 xustar000000000000000030 mtime=1386699096.471032554 30 atime=1386699096.471032554 30 ctime=1386699096.471032554 edfbrowser_153_source/edflib.c0000644000175000001440000037425312251654530017307 0ustar00novarausers00000000000000/* ***************************************************************************** * * Copyright (c) 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * All rights reserved. * * email: teuniz@gmail.com * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY Teunis van Beelen ''AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL Teunis van Beelen BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************************** */ /* compile with options "-D_LARGEFILE64_SOURCE -D_LARGEFILE_SOURCE" */ #include "edflib.h" #define EDFLIB_VERSION 110 #define EDFLIB_MAXFILES 64 #if defined(__APPLE__) || defined(__MACH__) || defined(__APPLE_CC__) #define fopeno fopen #else #define fseeko fseeko64 #define ftello ftello64 #define fopeno fopen64 #endif #ifdef _WIN32 #ifndef __MINGW32__ /* needed for visual c */ #undef fseeko #define fseeko _fseeki64 #undef ftello #define ftello _ftelli64 #undef fopeno #define fopeno fopen #endif #endif /* max size of annotationtext */ #define EDFLIB_WRITE_MAX_ANNOTATION_LEN 40 /* bytes in datarecord for EDF annotations, must be a multiple of three and two */ #define EDFLIB_ANNOTATION_BYTES 114 struct edfparamblock{ char label[17]; char transducer[81]; char physdimension[9]; double phys_min; double phys_max; int dig_min; int dig_max; char prefilter[81]; int smp_per_record; char reserved[33]; double offset; int buf_offset; double bitvalue; int annotation; long long sample_pntr; }; struct edfhdrblock{ FILE *file_hdl; char path[1024]; int writemode; char version[32]; char patient[81]; char recording[81]; char plus_patientcode[81]; char plus_gender[16]; char plus_birthdate[16]; char plus_patient_name[81]; char plus_patient_additional[81]; char plus_startdate[16]; char plus_admincode[81]; char plus_technician[81]; char plus_equipment[81]; char plus_recording_additional[81]; long long l_starttime; int startdate_day; int startdate_month; int startdate_year; int starttime_second; int starttime_minute; int starttime_hour; char reserved[45]; int hdrsize; int edfsignals; long long datarecords; int recordsize; int annot_ch[EDFLIB_MAXSIGNALS]; int nr_annot_chns; int mapped_signals[EDFLIB_MAXSIGNALS]; int edf; int edfplus; int bdf; int bdfplus; int discontinuous; int signal_write_sequence_pos; long long starttime_offset; double data_record_duration; long long long_data_record_duration; long long annots_in_file; int total_annot_bytes; int eq_sf; struct edfparamblock *edfparam; }; struct edf_annotationblock{ long long onset; char duration[16]; char annotation[EDFLIB_MAX_ANNOTATION_LEN + 1]; struct edf_annotationblock *former_annotation; struct edf_annotationblock *next_annotation; } *annotationslist[EDFLIB_MAXFILES]; struct edf_write_annotationblock{ long long onset; long long duration; char annotation[EDFLIB_WRITE_MAX_ANNOTATION_LEN + 1]; struct edf_write_annotationblock *former_annotation; struct edf_write_annotationblock *next_annotation; } *write_annotationslist[EDFLIB_MAXFILES]; static int files_open=0; static struct edfhdrblock *hdrlist[EDFLIB_MAXFILES]; struct edfhdrblock * edflib_check_edf_file(FILE *, int *); int edflib_is_integer_number(char *); int edflib_is_number(char *); long long edflib_get_long_duration(char *); int edflib_get_annotations(struct edfhdrblock *, int, int); int edflib_is_duration_number(char *); int edflib_is_onset_number(char *); long long edflib_get_long_time(char *); int edflib_write_edf_header(struct edfhdrblock *); void edflib_latin1_to_ascii(char *, int); void edflib_latin12utf8(char *, int); void edflib_remove_padding_trailing_spaces(char *); int edflib_atoi_nonlocalized(const char *); double edflib_atof_nonlocalized(const char *); int edflib_sprint_number_nonlocalized(char *, double); int edflib_sprint_int_number_nonlocalized(char *, int, int, int); int edflib_sprint_ll_number_nonlocalized(char *, long long, int, int); int edflib_fprint_int_number_nonlocalized(FILE *, int, int, int); int edflib_fprint_ll_number_nonlocalized(FILE *, long long, int, int); int edflib_is_file_used(const char *path) { int i, file_used=0; for(i=0; ipath))) { file_used = 1; break; } } } return(file_used); } int edflib_get_number_of_open_files() { return(files_open); } int edflib_get_handle(int file_number) { int i, file_count=0; for(i=0; ifiletype = EDFLIB_INVALID_READ_ANNOTS_VALUE; return(-1); } if(read_annotations>2) { edfhdr->filetype = EDFLIB_INVALID_READ_ANNOTS_VALUE; return(-1); } memset(edfhdr, 0, sizeof(struct edf_hdr_struct)); if(files_open>=EDFLIB_MAXFILES) { edfhdr->filetype = EDFLIB_MAXFILES_REACHED; return(-1); } for(i=0; ipath))) { edfhdr->filetype = EDFLIB_FILE_ALREADY_OPENED; return(-1); } } } file = fopeno(path, "rb"); if(file==NULL) { edfhdr->filetype = EDFLIB_NO_SUCH_FILE_OR_DIRECTORY; return(-1); } hdr = edflib_check_edf_file(file, &edf_error); if(hdr==NULL) { edfhdr->filetype = edf_error; fclose(file); return(-1); } if(hdr->discontinuous) { edfhdr->filetype = EDFLIB_FILE_IS_DISCONTINUOUS; free(hdr->edfparam); free(hdr); fclose(file); return(-1); } hdr->writemode = 0; for(i=0; ihandle = i; break; } } if((hdr->edf)&&(!(hdr->edfplus))) { edfhdr->filetype = EDFLIB_FILETYPE_EDF; } if(hdr->edfplus) { edfhdr->filetype = EDFLIB_FILETYPE_EDFPLUS; } if((hdr->bdf)&&(!(hdr->bdfplus))) { edfhdr->filetype = EDFLIB_FILETYPE_BDF; } if(hdr->bdfplus) { edfhdr->filetype = EDFLIB_FILETYPE_BDFPLUS; } edfhdr->edfsignals = hdr->edfsignals - hdr->nr_annot_chns; edfhdr->file_duration = hdr->long_data_record_duration * hdr->datarecords; edfhdr->startdate_day = hdr->startdate_day; edfhdr->startdate_month = hdr->startdate_month; edfhdr->startdate_year = hdr->startdate_year; edfhdr->starttime_hour = hdr->starttime_hour; edfhdr->starttime_second = hdr->starttime_second; edfhdr->starttime_minute = hdr->starttime_minute; edfhdr->starttime_subsecond = hdr->starttime_offset; edfhdr->datarecords_in_file = hdr->datarecords; edfhdr->datarecord_duration = hdr->long_data_record_duration; if((!(hdr->edfplus))&&(!(hdr->bdfplus))) { strcpy(edfhdr->patient, hdr->patient); strcpy(edfhdr->recording, hdr->recording); edfhdr->patientcode[0] = 0; edfhdr->gender[0] = 0; edfhdr->birthdate[0] = 0; edfhdr->patient_name[0] = 0; edfhdr->patient_additional[0] = 0; edfhdr->admincode[0] = 0; edfhdr->technician[0] = 0; edfhdr->equipment[0] = 0; edfhdr->recording_additional[0] = 0; } else { edfhdr->patient[0] = 0; edfhdr->recording[0] = 0; strcpy(edfhdr->patientcode, hdr->plus_patientcode); strcpy(edfhdr->gender, hdr->plus_gender); strcpy(edfhdr->birthdate, hdr->plus_birthdate); strcpy(edfhdr->patient_name, hdr->plus_patient_name); strcpy(edfhdr->patient_additional, hdr->plus_patient_additional); strcpy(edfhdr->admincode, hdr->plus_admincode); strcpy(edfhdr->technician, hdr->plus_technician); strcpy(edfhdr->equipment, hdr->plus_equipment); strcpy(edfhdr->recording_additional, hdr->plus_recording_additional); annotationslist[edfhdr->handle] = NULL; if((read_annotations==EDFLIB_READ_ANNOTATIONS)||(read_annotations==EDFLIB_READ_ALL_ANNOTATIONS)) { if(edflib_get_annotations(hdr, edfhdr->handle, read_annotations)) { edfhdr->filetype = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; if(annotationslist[edfhdr->handle]) { annot = annotationslist[edfhdr->handle]; while(annot->next_annotation) { annot = annot->next_annotation; free(annot->former_annotation); } free(annot); } fclose(file); free(hdr->edfparam); free(hdr); return(-1); } } } if(annotationslist[edfhdr->handle]) { hdr->annots_in_file++; annot = annotationslist[edfhdr->handle]; while(annot->next_annotation) { hdr->annots_in_file++; annot = annot->next_annotation; } } edfhdr->annotations_in_file = hdr->annots_in_file; strcpy(hdr->path, path); files_open++; j = 0; for(i=0; iedfsignals; i++) { if(!(hdr->edfparam[i].annotation)) { hdr->mapped_signals[j++] = i; } } for(i=0; iedfsignals; i++) { channel = hdr->mapped_signals[i]; strcpy(edfhdr->signalparam[i].label, hdr->edfparam[channel].label); strcpy(edfhdr->signalparam[i].transducer, hdr->edfparam[channel].transducer); strcpy(edfhdr->signalparam[i].physdimension, hdr->edfparam[channel].physdimension); strcpy(edfhdr->signalparam[i].prefilter, hdr->edfparam[channel].prefilter); edfhdr->signalparam[i].smp_in_file = hdr->edfparam[channel].smp_per_record * hdr->datarecords; edfhdr->signalparam[i].phys_max = hdr->edfparam[channel].phys_max; edfhdr->signalparam[i].phys_min = hdr->edfparam[channel].phys_min; edfhdr->signalparam[i].dig_max = hdr->edfparam[channel].dig_max; edfhdr->signalparam[i].dig_min = hdr->edfparam[channel].dig_min; edfhdr->signalparam[i].smp_in_datarecord = hdr->edfparam[channel].smp_per_record; } return(0); } int edfclose_file(int handle) { struct edf_annotationblock *annot; struct edf_write_annotationblock *annot2; int i, j, n, p, datrecsize, nmemb; long long offset, datarecords; char str[EDFLIB_ANNOTATION_BYTES * 2]; struct edfhdrblock *hdr; if(handle<0) { return(-1); } if(handle>=EDFLIB_MAXFILES) { return(-1); } if(hdrlist[handle]==NULL) { return(-1); } hdr = hdrlist[handle]; if(hdr->writemode) { if(hdr->datarecords == 0LL) { if(edflib_write_edf_header(hdr)) { return(-1); } annot2 = write_annotationslist[handle]; while(annot2) { p = edflib_fprint_ll_number_nonlocalized(hdr->file_hdl, (hdr->datarecords * hdr->long_data_record_duration) / EDFLIB_TIME_DIMENSION, 0, 1); if(hdr->long_data_record_duration % EDFLIB_TIME_DIMENSION) { fputc('.', hdr->file_hdl); p++; p += edflib_fprint_ll_number_nonlocalized(hdr->file_hdl, (hdr->datarecords * hdr->long_data_record_duration) % EDFLIB_TIME_DIMENSION, 7, 0); } fputc(20, hdr->file_hdl); fputc(20, hdr->file_hdl); p += 2; for(; ptotal_annot_bytes; p++) { fputc(0, hdr->file_hdl); } hdr->datarecords++; annot2 = annot2->next_annotation; } } if(hdr->datarecords<100000000LL) { fseeko(hdr->file_hdl, 236LL, SEEK_SET); p = edflib_fprint_int_number_nonlocalized(hdr->file_hdl, (int)(hdr->datarecords), 0, 0); if(p < 2) { fputc(' ', hdr->file_hdl); } } annot2 = write_annotationslist[handle]; datarecords = 0LL; offset = (long long)((hdr->edfsignals + hdr->nr_annot_chns + 1) * 256); datrecsize = hdr->total_annot_bytes; for(i=0; iedfsignals; i++) { if(hdr->edf) { offset += (long long)(hdr->edfparam[i].smp_per_record * 2); datrecsize += (hdr->edfparam[i].smp_per_record * 2); } else { offset += (long long)(hdr->edfparam[i].smp_per_record * 3); datrecsize += (hdr->edfparam[i].smp_per_record * 3); } } j = 0; while(annot2!=NULL) { p = 0; if(j==0) // first annotation signal { if(fseeko(hdr->file_hdl, offset, SEEK_SET)) { break; } p += edflib_sprint_ll_number_nonlocalized(str, (datarecords * hdr->long_data_record_duration) / EDFLIB_TIME_DIMENSION, 0, 1); if(hdr->long_data_record_duration % EDFLIB_TIME_DIMENSION) { str[p++] = '.'; n = edflib_sprint_ll_number_nonlocalized(str + p, (datarecords * hdr->long_data_record_duration) % EDFLIB_TIME_DIMENSION, 7, 0); p += n; } str[p++] = 20; str[p++] = 20; str[p++] = 0; } n = edflib_sprint_ll_number_nonlocalized(str + p, annot2->onset / 10000LL, 0, 1); p += n; if(annot2->onset % 10000LL) { str[p++] = '.'; n = edflib_sprint_ll_number_nonlocalized(str + p, annot2->onset % 10000LL, 4, 0); p += n; } if(annot2->duration>=0LL) { str[p++] = 21; n = edflib_sprint_ll_number_nonlocalized(str + p, annot2->duration / 10000LL, 0, 0); p += n; if(annot2->duration % 10000LL) { str[p++] = '.'; n = edflib_sprint_ll_number_nonlocalized(str + p, annot2->duration % 10000LL, 4, 0); p += n; } } str[p++] = 20; for(i=0; iannotation[i]==0) { break; } str[p++] = annot2->annotation[i]; } str[p++] = 20; for(; pfile_hdl); if(nmemb != 1) { break; } j++; if(j >= hdr->nr_annot_chns) { j = 0; offset += datrecsize; datarecords++; if(datarecords>=hdr->datarecords) { break; } } annot2 = annot2->next_annotation; } fclose(hdr->file_hdl); if(write_annotationslist[handle]!=NULL) { annot2 = write_annotationslist[handle]; while(annot2->next_annotation) { annot2 = annot2->next_annotation; free(annot2->former_annotation); } free(annot2); } free(hdr->edfparam); free(hdr); hdrlist[handle] = NULL; files_open--; return(0); } else { if(annotationslist[handle]!=NULL) { annot = annotationslist[handle]; while(annot->next_annotation) { annot = annot->next_annotation; free(annot->former_annotation); } free(annot); } fclose(hdr->file_hdl); free(hdr->edfparam); free(hdr); hdrlist[handle] = NULL; files_open--; return(0); } return(-1); /* we never reach this line */ } long long edfseek(int handle, int edfsignal, long long offset, int whence) { long long smp_in_file; int channel; if(handle<0) { return(-1); } if(handle>=EDFLIB_MAXFILES) { return(-1); } if(hdrlist[handle]==NULL) { return(-1); } if(edfsignal<0) { return(-1); } if(hdrlist[handle]->writemode) { return(-1); } if(edfsignal>=(hdrlist[handle]->edfsignals - hdrlist[handle]->nr_annot_chns)) { return(-1); } channel = hdrlist[handle]->mapped_signals[edfsignal]; smp_in_file = hdrlist[handle]->edfparam[channel].smp_per_record * hdrlist[handle]->datarecords; if(whence==EDFSEEK_SET) { hdrlist[handle]->edfparam[channel].sample_pntr = offset; } if(whence==EDFSEEK_CUR) { hdrlist[handle]->edfparam[channel].sample_pntr += offset; } if(whence==EDFSEEK_END) { hdrlist[handle]->edfparam[channel].sample_pntr = (hdrlist[handle]->edfparam[channel].smp_per_record * hdrlist[handle]->datarecords) + offset; } if(hdrlist[handle]->edfparam[channel].sample_pntr > smp_in_file) { hdrlist[handle]->edfparam[channel].sample_pntr = smp_in_file; } if(hdrlist[handle]->edfparam[channel].sample_pntr < 0LL) { hdrlist[handle]->edfparam[channel].sample_pntr = 0LL; } return(hdrlist[handle]->edfparam[channel].sample_pntr); } long long edftell(int handle, int edfsignal) { int channel; if(handle<0) { return(-1); } if(handle>=EDFLIB_MAXFILES) { return(-1); } if(hdrlist[handle]==NULL) { return(-1); } if(edfsignal<0) { return(-1); } if(hdrlist[handle]->writemode) { return(-1); } if(edfsignal>=(hdrlist[handle]->edfsignals - hdrlist[handle]->nr_annot_chns)) { return(-1); } channel = hdrlist[handle]->mapped_signals[edfsignal]; return(hdrlist[handle]->edfparam[channel].sample_pntr); } void edfrewind(int handle, int edfsignal) { int channel; if(handle<0) { return; } if(handle>=EDFLIB_MAXFILES) { return; } if(hdrlist[handle]==NULL) { return; } if(edfsignal<0) { return; } if(hdrlist[handle]->writemode) { return; } if(edfsignal>=(hdrlist[handle]->edfsignals - hdrlist[handle]->nr_annot_chns)) { return; } channel = hdrlist[handle]->mapped_signals[edfsignal]; hdrlist[handle]->edfparam[channel].sample_pntr = 0LL; } int edfread_physical_samples(int handle, int edfsignal, int n, double *buf) { int bytes_per_smpl=2, tmp, i, channel; double phys_bitvalue, phys_offset; long long smp_in_file, offset, sample_pntr, smp_per_record, jump; struct edfhdrblock *hdr; union { unsigned int one; signed int one_signed; unsigned short two[2]; signed short two_signed[2]; unsigned char four[4]; } var; FILE *file; if(handle<0) { return(-1); } if(handle>=EDFLIB_MAXFILES) { return(-1); } if(hdrlist[handle]==NULL) { return(-1); } if(edfsignal<0) { return(-1); } if(hdrlist[handle]->writemode) { return(-1); } if(edfsignal>=(hdrlist[handle]->edfsignals - hdrlist[handle]->nr_annot_chns)) { return(-1); } channel = hdrlist[handle]->mapped_signals[edfsignal]; if(n<0LL) { return(-1); } if(n==0LL) { return(0LL); } hdr = hdrlist[handle]; if(hdr->edf) { bytes_per_smpl = 2; } if(hdr->bdf) { bytes_per_smpl = 3; } smp_in_file = hdr->edfparam[channel].smp_per_record * hdr->datarecords; if((hdr->edfparam[channel].sample_pntr + n) > smp_in_file) { n = smp_in_file - hdr->edfparam[channel].sample_pntr; if(n==0) { return(0LL); } if(n<0) { return(-1); } } file = hdr->file_hdl; offset = hdr->hdrsize; offset += (hdr->edfparam[channel].sample_pntr / hdr->edfparam[channel].smp_per_record) * hdr->recordsize; offset += hdr->edfparam[channel].buf_offset; offset += ((hdr->edfparam[channel].sample_pntr % hdr->edfparam[channel].smp_per_record) * bytes_per_smpl); fseeko(file, offset, SEEK_SET); sample_pntr = hdr->edfparam[channel].sample_pntr; smp_per_record = hdr->edfparam[channel].smp_per_record; jump = hdr->recordsize - (smp_per_record * bytes_per_smpl); phys_bitvalue = hdr->edfparam[channel].bitvalue; phys_offset = hdr->edfparam[channel].offset; if(hdr->edf) { for(i=0; ibdf) { for(i=0; iedfparam[channel].sample_pntr = sample_pntr; return(n); } int edfread_digital_samples(int handle, int edfsignal, int n, int *buf) { int bytes_per_smpl=2, tmp, i, channel; long long smp_in_file, offset, sample_pntr, smp_per_record, jump; struct edfhdrblock *hdr; union { unsigned int one; signed int one_signed; unsigned short two[2]; signed short two_signed[2]; unsigned char four[4]; } var; FILE *file; if(handle<0) { return(-1); } if(handle>=EDFLIB_MAXFILES) { return(-1); } if(hdrlist[handle]==NULL) { return(-1); } if(edfsignal<0) { return(-1); } if(hdrlist[handle]->writemode) { return(-1); } if(edfsignal>=(hdrlist[handle]->edfsignals - hdrlist[handle]->nr_annot_chns)) { return(-1); } channel = hdrlist[handle]->mapped_signals[edfsignal]; if(n<0LL) { return(-1); } if(n==0LL) { return(0LL); } hdr = hdrlist[handle]; if(hdr->edf) { bytes_per_smpl = 2; } if(hdr->bdf) { bytes_per_smpl = 3; } smp_in_file = hdr->edfparam[channel].smp_per_record * hdr->datarecords; if((hdr->edfparam[channel].sample_pntr + n) > smp_in_file) { n = smp_in_file - hdr->edfparam[channel].sample_pntr; if(n==0) { return(0LL); } if(n<0) { return(-1); } } file = hdr->file_hdl; offset = hdr->hdrsize; offset += (hdr->edfparam[channel].sample_pntr / hdr->edfparam[channel].smp_per_record) * hdr->recordsize; offset += hdr->edfparam[channel].buf_offset; offset += ((hdr->edfparam[channel].sample_pntr % hdr->edfparam[channel].smp_per_record) * bytes_per_smpl); fseeko(file, offset, SEEK_SET); sample_pntr = hdr->edfparam[channel].sample_pntr; smp_per_record = hdr->edfparam[channel].smp_per_record; jump = hdr->recordsize - (smp_per_record * bytes_per_smpl); if(hdr->edf) { for(i=0; ibdf) { for(i=0; iedfparam[channel].sample_pntr = sample_pntr; return(n); } int edf_get_annotation(int handle, int n, struct edf_annotation_struct *annot) { int i; struct edf_annotationblock *list_annot; memset(annot, 0, sizeof(struct edf_annotation_struct)); if(handle<0) { return(-1); } if(handle>=EDFLIB_MAXFILES) { return(-1); } if(hdrlist[handle]==NULL) { return(-1); } if(hdrlist[handle]->writemode) { return(-1); } if(n<0) { return(-1); } if(n>=hdrlist[handle]->annots_in_file) { return(-1); } list_annot = annotationslist[handle]; if(list_annot==NULL) { return(-1); } for(i=0; inext_annotation==NULL) { return(-1); } list_annot = list_annot->next_annotation; } annot->onset = list_annot->onset; strcpy(annot->duration, list_annot->duration); strcpy(annot->annotation, list_annot->annotation); return(0); } struct edfhdrblock * edflib_check_edf_file(FILE *inputfile, int *edf_error) { int i, j, p, r=0, n, dotposition, error; char *edf_hdr, scratchpad[128], scratchpad2[64]; struct edfhdrblock *edfhdr; /***************** check header ******************************/ edf_hdr = (char *)calloc(1, 256); if(edf_hdr==NULL) { *edf_error = EDFLIB_MALLOC_ERROR; return(NULL); } edfhdr = (struct edfhdrblock *)calloc(1, sizeof(struct edfhdrblock)); if(edfhdr==NULL) { free(edf_hdr); *edf_error = EDFLIB_MALLOC_ERROR; return(NULL); } rewind(inputfile); if(fread(edf_hdr, 256, 1, inputfile)!=1) { *edf_error = EDFLIB_FILE_READ_ERROR; free(edf_hdr); free(edfhdr); return(NULL); } /**************************** VERSION ***************************************/ strncpy(scratchpad, edf_hdr, 8); scratchpad[8] = 0; if(((signed char *)scratchpad)[0]==-1) /* BDF-file */ { for(i=1; i<8; i++) { if((scratchpad[i]<32)||(scratchpad[i]>126)) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr); return(NULL); } } if(strcmp(scratchpad + 1, "BIOSEMI")) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr); return(NULL); } edfhdr->bdf = 1; } else /* EDF-file */ { for(i=0; i<8; i++) { if((scratchpad[i]<32)||(scratchpad[i]>126)) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr); return(NULL); } } if(strcmp(scratchpad, "0 ")) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr); return(NULL); } edfhdr->edf = 1; } strncpy(edfhdr->version, edf_hdr, 8); edfhdr->version[8] = 0; if(edfhdr->bdf) edfhdr->version[0] = '.'; /********************* PATIENTNAME *********************************************/ strncpy(scratchpad, edf_hdr + 8, 80); scratchpad[80] = 0; for(i=0; i<80; i++) { if((((unsigned char *)scratchpad)[i]<32)||(((unsigned char *)scratchpad)[i]>126)) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr); return(NULL); } } strncpy(edfhdr->patient, edf_hdr + 8, 80); edfhdr->patient[80] = 0; /********************* RECORDING *********************************************/ strncpy(scratchpad, edf_hdr + 88, 80); scratchpad[80] = 0; for(i=0; i<80; i++) { if((((unsigned char *)scratchpad)[i]<32)||(((unsigned char *)scratchpad)[i]>126)) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr); return(NULL); } } strncpy(edfhdr->recording, edf_hdr + 88, 80); edfhdr->recording[80] = 0; /********************* STARTDATE *********************************************/ strncpy(scratchpad, edf_hdr + 168, 8); scratchpad[8] = 0; for(i=0; i<8; i++) { if((scratchpad[i]<32)||(scratchpad[i]>126)) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr); return(NULL); } } error = 0; if((edf_hdr[170]!='.')||(edf_hdr[173]!='.')) error = 1; if((edf_hdr[168]<48)||(edf_hdr[168]>57)) error = 1; if((edf_hdr[169]<48)||(edf_hdr[169]>57)) error = 1; if((edf_hdr[171]<48)||(edf_hdr[171]>57)) error = 1; if((edf_hdr[172]<48)||(edf_hdr[172]>57)) error = 1; if((edf_hdr[174]<48)||(edf_hdr[174]>57)) error = 1; if((edf_hdr[175]<48)||(edf_hdr[175]>57)) error = 1; strncpy(scratchpad, edf_hdr + 168, 8); if(error) { scratchpad[8] = 0; *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr); return(NULL); } scratchpad[2] = 0; scratchpad[5] = 0; scratchpad[8] = 0; if((edflib_atof_nonlocalized(scratchpad)<1)||(edflib_atof_nonlocalized(scratchpad)>31)) { strncpy(scratchpad, edf_hdr + 168, 8); scratchpad[8] = 0; *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr); return(NULL); } if((edflib_atof_nonlocalized(scratchpad+3)<1)||(edflib_atof_nonlocalized(scratchpad+3)>12)) { strncpy(scratchpad, edf_hdr + 168, 8); scratchpad[8] = 0; *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr); return(NULL); } edfhdr->startdate_day = edflib_atof_nonlocalized(scratchpad); edfhdr->startdate_month = edflib_atof_nonlocalized(scratchpad + 3); edfhdr->startdate_year = edflib_atof_nonlocalized(scratchpad + 6); if(edfhdr->startdate_year>84) { edfhdr->startdate_year += 1900; } else { edfhdr->startdate_year += 2000; } /********************* STARTTIME *********************************************/ strncpy(scratchpad, edf_hdr + 176, 8); scratchpad[8] = 0; for(i=0; i<8; i++) { if((scratchpad[i]<32)||(scratchpad[i]>126)) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr); return(NULL); } } error = 0; if((edf_hdr[178]!='.')||(edf_hdr[181]!='.')) error = 1; if((edf_hdr[176]<48)||(edf_hdr[176]>57)) error = 1; if((edf_hdr[177]<48)||(edf_hdr[177]>57)) error = 1; if((edf_hdr[179]<48)||(edf_hdr[179]>57)) error = 1; if((edf_hdr[180]<48)||(edf_hdr[180]>57)) error = 1; if((edf_hdr[182]<48)||(edf_hdr[182]>57)) error = 1; if((edf_hdr[183]<48)||(edf_hdr[183]>57)) error = 1; strncpy(scratchpad, edf_hdr + 176, 8); if(error) { strncpy(scratchpad, edf_hdr + 176, 8); scratchpad[8] = 0; *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr); return(NULL); } scratchpad[2] = 0; scratchpad[5] = 0; scratchpad[8] = 0; if(edflib_atof_nonlocalized(scratchpad)>23) { strncpy(scratchpad, edf_hdr + 176, 8); scratchpad[8] = 0; *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr); return(NULL); } if(edflib_atof_nonlocalized(scratchpad+3)>59) { strncpy(scratchpad, edf_hdr + 176, 8); scratchpad[8] = 0; *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr); return(NULL); } if(edflib_atof_nonlocalized(scratchpad+6)>59) { strncpy(scratchpad, edf_hdr + 176, 8); scratchpad[8] = 0; *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr); return(NULL); } edfhdr->starttime_hour = edflib_atof_nonlocalized(scratchpad); edfhdr->starttime_minute = edflib_atof_nonlocalized(scratchpad + 3); edfhdr->starttime_second = edflib_atof_nonlocalized(scratchpad + 6); edfhdr->l_starttime = 3600 * edflib_atof_nonlocalized(scratchpad); edfhdr->l_starttime += 60 * edflib_atof_nonlocalized(scratchpad + 3); edfhdr->l_starttime += edflib_atof_nonlocalized(scratchpad + 6); edfhdr->l_starttime *= EDFLIB_TIME_DIMENSION; /***************** NUMBER OF SIGNALS IN HEADER *******************************/ strncpy(scratchpad, edf_hdr + 252, 4); scratchpad[4] = 0; for(i=0; i<4; i++) { if((scratchpad[i]<32)||(scratchpad[i]>126)) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr); return(NULL); } } if(edflib_is_integer_number(scratchpad)) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr); return(NULL); } edfhdr->edfsignals = edflib_atof_nonlocalized(scratchpad); if(edfhdr->edfsignals<1) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr); return(NULL); } if(edfhdr->edfsignals>EDFLIB_MAXSIGNALS) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr); return(NULL); } /***************** NUMBER OF BYTES IN HEADER *******************************/ strncpy(scratchpad, edf_hdr + 184, 8); scratchpad[8] = 0; for(i=0; i<8; i++) { if((scratchpad[i]<32)||(scratchpad[i]>126)) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr); return(NULL); } } if(edflib_is_integer_number(scratchpad)) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr); return(NULL); } n = edflib_atof_nonlocalized(scratchpad); if((edfhdr->edfsignals * 256 + 256)!=n) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr); return(NULL); } /********************* RESERVED FIELD *************************************/ edfhdr->edfplus = 0; edfhdr->discontinuous = 0; strncpy(scratchpad, edf_hdr + 192, 44); scratchpad[44] = 0; for(i=0; i<44; i++) { if((scratchpad[i]<32)||(scratchpad[i]>126)) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr); return(NULL); } } if(edfhdr->edf) { if(!strncmp(scratchpad, "EDF+C", 5)) { edfhdr->edfplus = 1; } if(!strncmp(scratchpad, "EDF+D", 5)) { edfhdr->edfplus = 1; edfhdr->discontinuous = 1; } } if(edfhdr->bdf) { if(!strncmp(scratchpad, "BDF+C", 5)) { edfhdr->bdfplus = 1; } if(!strncmp(scratchpad, "BDF+D", 5)) { edfhdr->bdfplus = 1; edfhdr->discontinuous = 1; } } strncpy(edfhdr->reserved, edf_hdr + 192, 44); edfhdr->reserved[44] = 0; /********************* NUMBER OF DATARECORDS *************************************/ strncpy(scratchpad, edf_hdr + 236, 8); scratchpad[8] = 0; for(i=0; i<8; i++) { if((scratchpad[i]<32)||(scratchpad[i]>126)) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr); return(NULL); } } if(edflib_is_integer_number(scratchpad)) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr); return(NULL); } edfhdr->datarecords = edflib_atof_nonlocalized(scratchpad); if(edfhdr->datarecords<1) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr); return(NULL); } /********************* DATARECORD DURATION *************************************/ strncpy(scratchpad, edf_hdr + 244, 8); scratchpad[8] = 0; for(i=0; i<8; i++) { if((scratchpad[i]<32)||(scratchpad[i]>126)) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr); return(NULL); } } if(edflib_is_number(scratchpad)) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr); return(NULL); } edfhdr->data_record_duration = edflib_atof_nonlocalized(scratchpad); if(edfhdr->data_record_duration < -0.000001) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr); return(NULL); } edfhdr->long_data_record_duration = edflib_get_long_duration(scratchpad); free(edf_hdr); /********************* START WITH THE SIGNALS IN THE HEADER *********************/ edf_hdr = (char *)calloc(1, (edfhdr->edfsignals + 1) * 256); if(edf_hdr==NULL) { *edf_error = EDFLIB_MALLOC_ERROR; free(edfhdr); return(NULL); } rewind(inputfile); if(fread(edf_hdr, (edfhdr->edfsignals + 1) * 256, 1, inputfile)!=1) { *edf_error = EDFLIB_FILE_READ_ERROR; free(edf_hdr); free(edfhdr); return(NULL); } edfhdr->edfparam = (struct edfparamblock *)calloc(1, sizeof(struct edfparamblock) * edfhdr->edfsignals); if(edfhdr->edfparam==NULL) { *edf_error = EDFLIB_MALLOC_ERROR; free(edf_hdr); free(edfhdr); return(NULL); } /**************************** LABELS *************************************/ edfhdr->nr_annot_chns = 0; for(i=0; iedfsignals; i++) { strncpy(scratchpad, edf_hdr + 256 + (i * 16), 16); for(j=0; j<16; j++) { if((scratchpad[j]<32)||(scratchpad[j]>126)) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } if(edfhdr->edfplus) { if(!strncmp(scratchpad, "EDF Annotations ", 16)) { edfhdr->annot_ch[edfhdr->nr_annot_chns] = i; edfhdr->nr_annot_chns++; edfhdr->edfparam[i].annotation = 1; } } if(edfhdr->bdfplus) { if(!strncmp(scratchpad, "BDF Annotations ", 16)) { edfhdr->annot_ch[edfhdr->nr_annot_chns] = i; edfhdr->nr_annot_chns++; edfhdr->edfparam[i].annotation = 1; } } strncpy(edfhdr->edfparam[i].label, edf_hdr + 256 + (i * 16), 16); edfhdr->edfparam[i].label[16] = 0; } if(edfhdr->edfplus&&(!edfhdr->nr_annot_chns)) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } if(edfhdr->bdfplus&&(!edfhdr->nr_annot_chns)) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } if((edfhdr->edfsignals!=edfhdr->nr_annot_chns)||((!edfhdr->edfplus)&&(!edfhdr->bdfplus))) { if(edfhdr->data_record_duration<0.0000001) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } /**************************** TRANSDUCER TYPES *************************************/ for(i=0; iedfsignals; i++) { strncpy(scratchpad, edf_hdr + 256 + (edfhdr->edfsignals * 16) + (i * 80), 80); for(j=0; j<80; j++) { if((scratchpad[j]<32)||(scratchpad[j]>126)) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } strncpy(edfhdr->edfparam[i].transducer, edf_hdr + 256 + (edfhdr->edfsignals * 16) + (i * 80), 80); edfhdr->edfparam[i].transducer[80] = 0; if((edfhdr->edfplus) || (edfhdr->bdfplus)) { if(edfhdr->edfparam[i].annotation) { for(j=0; j<80; j++) { if(edfhdr->edfparam[i].transducer[j]!=' ') { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } } } } /**************************** PHYSICAL DIMENSIONS *************************************/ for(i=0; iedfsignals; i++) { strncpy(scratchpad, edf_hdr + 256 + (edfhdr->edfsignals * 96) + (i * 8), 8); for(j=0; j<8; j++) { if((scratchpad[j]<32)||(scratchpad[j]>126)) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } strncpy(edfhdr->edfparam[i].physdimension, edf_hdr + 256 + (edfhdr->edfsignals * 96) + (i * 8), 8); edfhdr->edfparam[i].physdimension[8] = 0; } /**************************** PHYSICAL MINIMUMS *************************************/ for(i=0; iedfsignals; i++) { strncpy(scratchpad, edf_hdr + 256 + (edfhdr->edfsignals * 104) + (i * 8), 8); scratchpad[8] = 0; for(j=0; j<8; j++) { if((scratchpad[j]<32)||(scratchpad[j]>126)) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } if(edflib_is_number(scratchpad)) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } edfhdr->edfparam[i].phys_min = edflib_atof_nonlocalized(scratchpad); } /**************************** PHYSICAL MAXIMUMS *************************************/ for(i=0; iedfsignals; i++) { strncpy(scratchpad, edf_hdr + 256 + (edfhdr->edfsignals * 112) + (i * 8), 8); scratchpad[8] = 0; for(j=0; j<8; j++) { if((scratchpad[j]<32)||(scratchpad[j]>126)) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } if(edflib_is_number(scratchpad)) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } edfhdr->edfparam[i].phys_max = edflib_atof_nonlocalized(scratchpad); if(edfhdr->edfparam[i].phys_max==edfhdr->edfparam[i].phys_min) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } /**************************** DIGITAL MINIMUMS *************************************/ for(i=0; iedfsignals; i++) { strncpy(scratchpad, edf_hdr + 256 + (edfhdr->edfsignals * 120) + (i * 8), 8); scratchpad[8] = 0; for(j=0; j<8; j++) { if((scratchpad[j]<32)||(scratchpad[j]>126)) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } if(edflib_is_integer_number(scratchpad)) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } n = edflib_atof_nonlocalized(scratchpad); if(edfhdr->edfplus) { if(edfhdr->edfparam[i].annotation) { if(n!=-32768) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } } if(edfhdr->bdfplus) { if(edfhdr->edfparam[i].annotation) { if(n!=-8388608) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } } if(edfhdr->edf) { if((n>32767)||(n<-32768)) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } if(edfhdr->bdf) { if((n>8388607)||(n<-8388608)) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } edfhdr->edfparam[i].dig_min = n; } /**************************** DIGITAL MAXIMUMS *************************************/ for(i=0; iedfsignals; i++) { strncpy(scratchpad, edf_hdr + 256 + (edfhdr->edfsignals * 128) + (i * 8), 8); scratchpad[8] = 0; for(j=0; j<8; j++) { if((scratchpad[j]<32)||(scratchpad[j]>126)) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } if(edflib_is_integer_number(scratchpad)) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } n = edflib_atof_nonlocalized(scratchpad); if(edfhdr->edfplus) { if(edfhdr->edfparam[i].annotation) { if(n!=32767) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } } if(edfhdr->bdfplus) { if(edfhdr->edfparam[i].annotation) { if(n!=8388607) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } } if(edfhdr->edf) { if((n>32767)||(n<-32768)) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } else { if((n>8388607)||(n<-8388608)) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } edfhdr->edfparam[i].dig_max = n; if(edfhdr->edfparam[i].dig_max<(edfhdr->edfparam[i].dig_min + 1)) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } /**************************** PREFILTER FIELDS *************************************/ for(i=0; iedfsignals; i++) { strncpy(scratchpad, edf_hdr + 256 + (edfhdr->edfsignals * 136) + (i * 80), 80); for(j=0; j<80; j++) { if((scratchpad[j]<32)||(scratchpad[j]>126)) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } strncpy(edfhdr->edfparam[i].prefilter, edf_hdr + 256 + (edfhdr->edfsignals * 136) + (i * 80), 80); edfhdr->edfparam[i].prefilter[80] = 0; if((edfhdr->edfplus) || (edfhdr->bdfplus)) { if(edfhdr->edfparam[i].annotation) { for(j=0; j<80; j++) { if(edfhdr->edfparam[i].prefilter[j]!=' ') { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } } } } /*********************** NR OF SAMPLES IN EACH DATARECORD ********************/ edfhdr->recordsize = 0; for(i=0; iedfsignals; i++) { strncpy(scratchpad, edf_hdr + 256 + (edfhdr->edfsignals * 216) + (i * 8), 8); scratchpad[8] = 0; for(j=0; j<8; j++) { if((scratchpad[j]<32)||(scratchpad[j]>126)) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } if(edflib_is_integer_number(scratchpad)) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } n = edflib_atof_nonlocalized(scratchpad); if(n<1) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } edfhdr->edfparam[i].smp_per_record = n; edfhdr->recordsize += n; } if(edfhdr->bdf) { edfhdr->recordsize *= 3; if(edfhdr->recordsize > 15728640) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } else { edfhdr->recordsize *= 2; if(edfhdr->recordsize > 10485760) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } /**************************** RESERVED FIELDS *************************************/ for(i=0; iedfsignals; i++) { strncpy(scratchpad, edf_hdr + 256 + (edfhdr->edfsignals * 224) + (i * 32), 32); for(j=0; j<32; j++) { if((scratchpad[j]<32)||(scratchpad[j]>126)) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } strncpy(edfhdr->edfparam[i].reserved, edf_hdr + 256 + (edfhdr->edfsignals * 224) + (i * 32), 32); edfhdr->edfparam[i].reserved[32] = 0; } /********************* EDF+ PATIENTNAME *********************************************/ if(edfhdr->edfplus || edfhdr->bdfplus) { error = 0; dotposition = 0; strncpy(scratchpad, edf_hdr + 8, 80); scratchpad[80] = 0; for(i=0; i<80; i++) { if(scratchpad[i]==' ') { dotposition = i; break; } } dotposition++; if((dotposition>73)||(dotposition<2)) error = 1; if(scratchpad[dotposition + 2]!='X') { if(dotposition>65) error = 1; } if((scratchpad[dotposition]!='M')&&(scratchpad[dotposition]!='F')&&(scratchpad[dotposition]!='X')) error = 1; dotposition++; if(scratchpad[dotposition]!=' ') error = 1; if(scratchpad[dotposition + 1]=='X') { if(scratchpad[dotposition + 2]!=' ') error = 1; if(scratchpad[dotposition + 3]==' ') error = 1; } else { if(scratchpad[dotposition + 12]!=' ') error = 1; if(scratchpad[dotposition + 13]==' ') error = 1; dotposition++; strncpy(scratchpad2, scratchpad + dotposition, 11); scratchpad2[11] = 0; if((scratchpad2[2]!='-')||(scratchpad2[6]!='-')) error = 1; scratchpad2[2] = 0; scratchpad2[6] = 0; if((scratchpad2[0]<48)||(scratchpad2[0]>57)) error = 1; if((scratchpad2[1]<48)||(scratchpad2[1]>57)) error = 1; if((scratchpad2[7]<48)||(scratchpad2[7]>57)) error = 1; if((scratchpad2[8]<48)||(scratchpad2[8]>57)) error = 1; if((scratchpad2[9]<48)||(scratchpad2[9]>57)) error = 1; if((scratchpad2[10]<48)||(scratchpad2[10]>57)) error = 1; if((edflib_atof_nonlocalized(scratchpad2)<1)||(edflib_atof_nonlocalized(scratchpad2)>31)) error = 1; if(strcmp(scratchpad2 + 3, "JAN")) if(strcmp(scratchpad2 + 3, "FEB")) if(strcmp(scratchpad2 + 3, "MAR")) if(strcmp(scratchpad2 + 3, "APR")) if(strcmp(scratchpad2 + 3, "MAY")) if(strcmp(scratchpad2 + 3, "JUN")) if(strcmp(scratchpad2 + 3, "JUL")) if(strcmp(scratchpad2 + 3, "AUG")) if(strcmp(scratchpad2 + 3, "SEP")) if(strcmp(scratchpad2 + 3, "OCT")) if(strcmp(scratchpad2 + 3, "NOV")) if(strcmp(scratchpad2 + 3, "DEC")) error = 1; } if(error) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } p = 0; if(edfhdr->patient[p]=='X') { edfhdr->plus_patientcode[0] = 0; p += 2; } else { for(i=0; i<(80-p); i++) { if(edfhdr->patient[i+p]==' ') { break; } edfhdr->plus_patientcode[i] = edfhdr->patient[i+p]; if(edfhdr->plus_patientcode[i]=='_') edfhdr->plus_patientcode[i] = ' '; } edfhdr->plus_patientcode[i] = 0; p += i + 1; } if(edfhdr->patient[p]=='M') { strcpy(edfhdr->plus_gender, "Male"); } if(edfhdr->patient[p]=='F') { strcpy(edfhdr->plus_gender, "Female"); } if(edfhdr->patient[p]=='X') { edfhdr->plus_gender[0] = 0; } for(i=0; i<(80-p);i++) { if(edfhdr->patient[i+p]==' ') { break; } } p += i + 1; if(edfhdr->patient[p]=='X') { edfhdr->plus_birthdate[0] = 0; p += 2; } else { for(i=0; i<(80-p); i++) { if(edfhdr->patient[i+p]==' ') { break; } edfhdr->plus_birthdate[i] = edfhdr->patient[i+p]; } edfhdr->plus_birthdate[2] = ' '; edfhdr->plus_birthdate[3] += 32; edfhdr->plus_birthdate[4] += 32; edfhdr->plus_birthdate[5] += 32; edfhdr->plus_birthdate[6] = ' '; edfhdr->plus_birthdate[11] = 0; p += i + 1; } for(i=0; i<(80-p);i++) { if(edfhdr->patient[i+p]==' ') { break; } edfhdr->plus_patient_name[i] = edfhdr->patient[i+p]; if(edfhdr->plus_patient_name[i]=='_') edfhdr->plus_patient_name[i] = ' '; } edfhdr->plus_patient_name[i] = 0; p += i + 1; for(i=0; i<(80-p);i++) { edfhdr->plus_patient_additional[i] = edfhdr->patient[i+p]; } edfhdr->plus_patient_additional[i] = 0; p += i + 1; } /********************* EDF+ RECORDINGFIELD *********************************************/ if(edfhdr->edfplus || edfhdr->bdfplus) { error = 0; strncpy(scratchpad, edf_hdr + 88, 80); scratchpad[80] = 0; if(strncmp(scratchpad, "Startdate ", 10)) error = 1; if(scratchpad[10]=='X') { if(scratchpad[11]!=' ') error = 1; if(scratchpad[12]==' ') error = 1; p = 12; } else { if(scratchpad[21]!=' ') error = 1; if(scratchpad[22]==' ') error = 1; p = 22; strncpy(scratchpad2, scratchpad + 10, 11); scratchpad2[11] = 0; if((scratchpad2[2]!='-')||(scratchpad2[6]!='-')) error = 1; scratchpad2[2] = 0; scratchpad2[6] = 0; if((scratchpad2[0]<48)||(scratchpad2[0]>57)) error = 1; if((scratchpad2[1]<48)||(scratchpad2[1]>57)) error = 1; if((scratchpad2[7]<48)||(scratchpad2[7]>57)) error = 1; if((scratchpad2[8]<48)||(scratchpad2[8]>57)) error = 1; if((scratchpad2[9]<48)||(scratchpad2[9]>57)) error = 1; if((scratchpad2[10]<48)||(scratchpad2[10]>57)) error = 1; if((edflib_atof_nonlocalized(scratchpad2)<1)||(edflib_atof_nonlocalized(scratchpad2)>31)) error = 1; r = 0; if(!strcmp(scratchpad2 + 3, "JAN")) r = 1; else if(!strcmp(scratchpad2 + 3, "FEB")) r = 2; else if(!strcmp(scratchpad2 + 3, "MAR")) r = 3; else if(!strcmp(scratchpad2 + 3, "APR")) r = 4; else if(!strcmp(scratchpad2 + 3, "MAY")) r = 5; else if(!strcmp(scratchpad2 + 3, "JUN")) r = 6; else if(!strcmp(scratchpad2 + 3, "JUL")) r = 7; else if(!strcmp(scratchpad2 + 3, "AUG")) r = 8; else if(!strcmp(scratchpad2 + 3, "SEP")) r = 9; else if(!strcmp(scratchpad2 + 3, "OCT")) r = 10; else if(!strcmp(scratchpad2 + 3, "NOV")) r = 11; else if(!strcmp(scratchpad2 + 3, "DEC")) r = 12; else error = 1; } n = 0; for(i=p; i<80; i++) { if(i>78) { error = 1; break; } if(scratchpad[i]==' ') { n++; if(scratchpad[i + 1]==' ') { error = 1; break; } } if(n>1) break; } if(error) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } if(edf_hdr[98]!='X') { error = 0; strncpy(scratchpad, edf_hdr + 168, 8); scratchpad[2] = 0; scratchpad[5] = 0; scratchpad[8] = 0; if(edflib_atof_nonlocalized(scratchpad)!=edflib_atof_nonlocalized(scratchpad2)) error = 1; if(edflib_atof_nonlocalized(scratchpad+3)!=r) error = 1; if(edflib_atof_nonlocalized(scratchpad+6)!=edflib_atof_nonlocalized(scratchpad2+9)) error = 1; if(error) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } edfhdr->startdate_year = edflib_atof_nonlocalized(scratchpad2 + 7); if(edfhdr->startdate_year<1970) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } p = 10; for(i=0; i<(80-p); i++) { if(edfhdr->recording[i+p]==' ') { break; } edfhdr->plus_startdate[i] = edfhdr->recording[i+p]; } edfhdr->plus_startdate[2] = ' '; edfhdr->plus_startdate[3] += 32; edfhdr->plus_startdate[4] += 32; edfhdr->plus_startdate[5] += 32; edfhdr->plus_startdate[6] = ' '; edfhdr->plus_startdate[11] = 0; p += i + 1; if(edfhdr->recording[p]=='X') { edfhdr->plus_admincode[0] = 0; p += 2; } else { for(i=0; i<(80-p); i++) { if(edfhdr->recording[i+p]==' ') { break; } edfhdr->plus_admincode[i] = edfhdr->recording[i+p]; if(edfhdr->plus_admincode[i]=='_') edfhdr->plus_admincode[i] = ' '; } edfhdr->plus_admincode[i] = 0; p += i + 1; } if(edfhdr->recording[p]=='X') { edfhdr->plus_technician[0] = 0; p += 2; } else { for(i=0; i<(80-p); i++) { if(edfhdr->recording[i+p]==' ') { break; } edfhdr->plus_technician[i] = edfhdr->recording[i+p]; if(edfhdr->plus_technician[i]=='_') edfhdr->plus_technician[i] = ' '; } edfhdr->plus_technician[i] = 0; p += i + 1; } if(edfhdr->recording[p]=='X') { edfhdr->plus_equipment[0] = 0; p += 2; } else { for(i=0; i<(80-p); i++) { if(edfhdr->recording[i+p]==' ') { break; } edfhdr->plus_equipment[i] = edfhdr->recording[i+p]; if(edfhdr->plus_equipment[i]=='_') edfhdr->plus_equipment[i] = ' '; } edfhdr->plus_equipment[i] = 0; p += i + 1; } for(i=0; i<(80-p);i++) { edfhdr->plus_recording_additional[i] = edfhdr->recording[i+p]; } edfhdr->plus_recording_additional[i] = 0; p += i + 1; } /********************* FILESIZE *********************************************/ edfhdr->hdrsize = edfhdr->edfsignals * 256 + 256; fseeko(inputfile, 0LL, SEEK_END); if(ftello(inputfile)!=(edfhdr->recordsize * edfhdr->datarecords + edfhdr->hdrsize)) { *edf_error = EDFLIB_FILE_CONTAINS_FORMAT_ERRORS; free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } n = 0; for(i=0; iedfsignals; i++) { edfhdr->edfparam[i].buf_offset = n; if(edfhdr->bdf) n += edfhdr->edfparam[i].smp_per_record * 3; else n += edfhdr->edfparam[i].smp_per_record * 2; edfhdr->edfparam[i].bitvalue = (edfhdr->edfparam[i].phys_max - edfhdr->edfparam[i].phys_min) / (edfhdr->edfparam[i].dig_max - edfhdr->edfparam[i].dig_min); edfhdr->edfparam[i].offset = edfhdr->edfparam[i].phys_max / edfhdr->edfparam[i].bitvalue - edfhdr->edfparam[i].dig_max; } edfhdr->file_hdl = inputfile; free(edf_hdr); return(edfhdr); } int edflib_is_integer_number(char *str) { int i=0, l, hasspace = 0, hassign=0, digit=0; l = strlen(str); if(!l) return(1); if((str[0]=='+')||(str[0]=='-')) { hassign++; i++; } for(; i57)) { return(1); } else { if(hasspace) { return(1); } digit++; } } } if(digit) return(0); else return(1); } int edflib_is_number(char *str) { int i=0, l, hasspace = 0, hassign=0, digit=0, hasdot=0, hasexp=0; l = strlen(str); if(!l) return(1); if((str[0]=='+')||(str[0]=='-')) { hassign++; i++; } for(; i57))&&str[i]!='.') { return(1); } else { if(hasspace) { return(1); } if(str[i]=='.') { if(hasdot) return(1); hasdot++; } else { digit++; } } } } if(hasexp) { if(++i==l) { return(1); } if((str[i]=='+')||(str[i]=='-')) { hassign++; i++; } for(; i57)) { return(1); } else { if(hasspace) { return(1); } digit++; } } } } if(digit) return(0); else return(1); } long long edflib_get_long_duration(char *str) { int i, len=8, hasdot=0, dotposition=0; long long value=0, radix; for(i=0; i<8; i++) { if(str[i]==' ') { len = i; break; } } for(i=0; i=0; i--) { value += ((long long)(str[i] - 48)) * radix; radix *= 10; } radix = EDFLIB_TIME_DIMENSION / 10; for(i=dotposition+1; i=0; i--) { value += ((long long)(str[i] - 48)) * radix; radix *= 10; } } return(value); } int edflib_version(void) { return(EDFLIB_VERSION); } int edflib_get_annotations(struct edfhdrblock *edfhdr, int hdl, int read_annotations) { 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; char *scratchpad, *cnv_buf, *time_in_txt, *duration_in_txt; long long data_record_duration, elapsedtime, time_tmp=0; FILE *inputfile; struct edfparamblock *edfparam; struct edf_annotationblock *new_annotation=NULL, *temp_annotation; inputfile = edfhdr->file_hdl; edfsignals = edfhdr->edfsignals; recordsize = edfhdr->recordsize; edfparam = edfhdr->edfparam; nr_annot_chns = edfhdr->nr_annot_chns; datarecords = edfhdr->datarecords; data_record_duration = edfhdr->long_data_record_duration; discontinuous = edfhdr->discontinuous; annot_ch = edfhdr->annot_ch; if(edfhdr->edfplus) { samplesize = 2; } if(edfhdr->bdfplus) { samplesize = 3; } cnv_buf = (char *)calloc(1, recordsize); if(cnv_buf==NULL) { return(1); } max_tal_ln = 0; for(i=0; i=EDFLIB_TIME_DIMENSION) { error = 2; goto END; } else { edfhdr->starttime_offset = time_tmp; } } elapsedtime = time_tmp; error = 0; break; } } } } for(k=0; k1) { 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 edf_annotationblock *)calloc(1, sizeof(struct edf_annotationblock)); if(new_annotation==NULL) { free(cnv_buf); free(scratchpad); free(time_in_txt); free(duration_in_txt); return(1); } new_annotation->next_annotation = NULL; new_annotation->annotation[0] = 0; if(duration) strcpy(new_annotation->duration, duration_in_txt); else new_annotation->duration[0] = 0; for(j=0; jannotation[j] = scratchpad[j]; } new_annotation->annotation[j] = 0; new_annotation->onset = edflib_get_long_time(time_in_txt); if(annotationslist[hdl]==NULL) { new_annotation->former_annotation = NULL; annotationslist[hdl] = new_annotation; } else { temp_annotation = annotationslist[hdl]; while(temp_annotation->next_annotation) temp_annotation = temp_annotation->next_annotation; new_annotation->former_annotation = temp_annotation; temp_annotation->next_annotation = new_annotation; } if(read_annotations==EDFLIB_READ_ANNOTATIONS) { if(!(strncmp(new_annotation->annotation, "Recording ends", 14))) { if(nr_annot_chns==1) { goto END; } } } } } annots_in_tal++; annots_in_record++; n = 0; continue; } if(!onset) { scratchpad[n] = 0; if(edflib_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(edflib_is_duration_number(scratchpad)) { error = 37; goto END; } for(j=0; j126)) { duration_in_txt[j] = '.'; } } duration_in_txt[j] = 0; duration = 1; duration_start = 0; n = 0; continue; } } n++; } END: /****************** end ************************/ if(error) { free(cnv_buf); free(scratchpad); free(time_in_txt); free(duration_in_txt); return(9); } } } free(cnv_buf); free(scratchpad); free(time_in_txt); free(duration_in_txt); return(0); } int edflib_is_duration_number(char *str) { int i, l, hasdot = 0; l = strlen(str); if(!l) return(1); if((str[0] == '.')||(str[l-1] == '.')) return(1); for(i=0; i57)) return(1); } } return(0); } int edflib_is_onset_number(char *str) { int i, l, hasdot = 0; l = strlen(str); if(l<2) return(1); if((str[0]!='+')&&(str[0]!='-')) return(1); if((str[1] == '.')||(str[l-1] == '.')) return(1); for(i=1; i57)) return(1); } } return(0); } long long edflib_get_long_time(char *str) { int i, len, hasdot=0, dotposition=0; long long value=0, radix; str = str + 1; len = strlen(str); for(i=0; i=0; i--) { value += ((long long)(str[i] - 48)) * radix; radix *= 10; } radix = EDFLIB_TIME_DIMENSION / 10; for(i=dotposition+1; i=0; i--) { value += ((long long)(str[i] - 48)) * radix; radix *= 10; } } if(str[-1]=='-') value = -value; return(value); } void edflib_latin1_to_ascii(char *str, int len) { int i, value; for(i=0; i31)&&(value<127)) { continue; } switch(value) { case 128 : str[i] = 'E'; break; case 130 : str[i] = ','; break; case 131 : str[i] = 'F'; break; case 132 : str[i] = '\"'; break; case 133 : str[i] = '.'; break; case 134 : str[i] = '+'; break; case 135 : str[i] = '+'; break; case 136 : str[i] = '^'; break; case 137 : str[i] = 'm'; break; case 138 : str[i] = 'S'; break; case 139 : str[i] = '<'; break; case 140 : str[i] = 'E'; break; case 142 : str[i] = 'Z'; break; case 145 : str[i] = '`'; break; case 146 : str[i] = '\''; break; case 147 : str[i] = '\"'; break; case 148 : str[i] = '\"'; break; case 149 : str[i] = '.'; break; case 150 : str[i] = '-'; break; case 151 : str[i] = '-'; break; case 152 : str[i] = '~'; break; case 154 : str[i] = 's'; break; case 155 : str[i] = '>'; break; case 156 : str[i] = 'e'; break; case 158 : str[i] = 'z'; break; case 159 : str[i] = 'Y'; break; case 171 : str[i] = '<'; break; case 180 : str[i] = '\''; break; case 181 : str[i] = 'u'; break; case 187 : str[i] = '>'; break; case 191 : str[i] = '\?'; break; case 192 : str[i] = 'A'; break; case 193 : str[i] = 'A'; break; case 194 : str[i] = 'A'; break; case 195 : str[i] = 'A'; break; case 196 : str[i] = 'A'; break; case 197 : str[i] = 'A'; break; case 198 : str[i] = 'E'; break; case 199 : str[i] = 'C'; break; case 200 : str[i] = 'E'; break; case 201 : str[i] = 'E'; break; case 202 : str[i] = 'E'; break; case 203 : str[i] = 'E'; break; case 204 : str[i] = 'I'; break; case 205 : str[i] = 'I'; break; case 206 : str[i] = 'I'; break; case 207 : str[i] = 'I'; break; case 208 : str[i] = 'D'; break; case 209 : str[i] = 'N'; break; case 210 : str[i] = 'O'; break; case 211 : str[i] = 'O'; break; case 212 : str[i] = 'O'; break; case 213 : str[i] = 'O'; break; case 214 : str[i] = 'O'; break; case 215 : str[i] = 'x'; break; case 216 : str[i] = 'O'; break; case 217 : str[i] = 'U'; break; case 218 : str[i] = 'U'; break; case 219 : str[i] = 'U'; break; case 220 : str[i] = 'U'; break; case 221 : str[i] = 'Y'; break; case 222 : str[i] = 'I'; break; case 223 : str[i] = 's'; break; case 224 : str[i] = 'a'; break; case 225 : str[i] = 'a'; break; case 226 : str[i] = 'a'; break; case 227 : str[i] = 'a'; break; case 228 : str[i] = 'a'; break; case 229 : str[i] = 'a'; break; case 230 : str[i] = 'e'; break; case 231 : str[i] = 'c'; break; case 232 : str[i] = 'e'; break; case 233 : str[i] = 'e'; break; case 234 : str[i] = 'e'; break; case 235 : str[i] = 'e'; break; case 236 : str[i] = 'i'; break; case 237 : str[i] = 'i'; break; case 238 : str[i] = 'i'; break; case 239 : str[i] = 'i'; break; case 240 : str[i] = 'd'; break; case 241 : str[i] = 'n'; break; case 242 : str[i] = 'o'; break; case 243 : str[i] = 'o'; break; case 244 : str[i] = 'o'; break; case 245 : str[i] = 'o'; break; case 246 : str[i] = 'o'; break; case 247 : str[i] = '-'; break; case 248 : str[i] = '0'; break; case 249 : str[i] = 'u'; break; case 250 : str[i] = 'u'; break; case 251 : str[i] = 'u'; break; case 252 : str[i] = 'u'; break; case 253 : str[i] = 'y'; break; case 254 : str[i] = 't'; break; case 255 : str[i] = 'y'; break; default : str[i] = ' '; break; } } } void edflib_latin12utf8(char *latin1_str, int len) { int i, j; unsigned char *str, tmp_str[512]; str = (unsigned char *)latin1_str; j = 0; for(i=0; i126)&&(str[i]<160)) tmp_str[j] = '.'; if(str[i]>159) { if((len-j)<2) { tmp_str[j] = ' '; } else { tmp_str[j] = 192 + (str[i]>>6); j++; tmp_str[j] = 128 + (str[i]&63); } } j++; if(j>=len) break; } for(i=0; i=EDFLIB_MAXFILES) { return(EDFLIB_MAXFILES_REACHED); } for(i=0; ipath))) { return(EDFLIB_FILE_ALREADY_OPENED); } } } if(number_of_signals<0) { return(EDFLIB_NUMBER_OF_SIGNALS_INVALID); } if(number_of_signals>EDFLIB_MAXSIGNALS) { return(EDFLIB_NUMBER_OF_SIGNALS_INVALID); } hdr = (struct edfhdrblock *)calloc(1, sizeof(struct edfhdrblock)); if(hdr==NULL) { return(EDFLIB_MALLOC_ERROR); } hdr->edfparam = (struct edfparamblock *)calloc(1, sizeof(struct edfparamblock) * number_of_signals); if(hdr->edfparam==NULL) { free(hdr); return(EDFLIB_MALLOC_ERROR); } hdr->writemode = 1; hdr->edfsignals = number_of_signals; file = fopeno(path, "wb"); if(file==NULL) { free(hdr->edfparam); free(hdr); return(EDFLIB_NO_SUCH_FILE_OR_DIRECTORY); } hdr->file_hdl = file; handle = -1; for(i=0; ipath, path); files_open++; if(filetype==EDFLIB_FILETYPE_EDFPLUS) { hdr->edf = 1; hdr->edfplus = 1; } if(filetype==EDFLIB_FILETYPE_BDFPLUS) { hdr->bdf = 1; hdr->bdfplus = 1; } hdr->long_data_record_duration = EDFLIB_TIME_DIMENSION; hdr->data_record_duration = 1.0; hdr->nr_annot_chns = 1; return(handle); } int edf_set_samplefrequency(int handle, int edfsignal, int samplefrequency) { if(handle<0) { return(-1); } if(handle>=EDFLIB_MAXFILES) { return(-1); } if(hdrlist[handle]==NULL) { return(-1); } if(!(hdrlist[handle]->writemode)) { return(-1); } if(edfsignal<0) { return(-1); } if(edfsignal>=hdrlist[handle]->edfsignals) { return(-1); } if(samplefrequency<1) { return(-1); } if(hdrlist[handle]->datarecords) { return(-1); } hdrlist[handle]->edfparam[edfsignal].smp_per_record = samplefrequency; return(0); } int edf_set_number_of_annotation_signals(int handle, int annot_signals) { if(handle<0) { return(-1); } if(handle>=EDFLIB_MAXFILES) { return(-1); } if(hdrlist[handle]==NULL) { return(-1); } if(!(hdrlist[handle]->writemode)) { return(-1); } if(hdrlist[handle]->datarecords) { return(-1); } if((annot_signals < 1) || (annot_signals > 64)) { return(-1); } hdrlist[handle]->nr_annot_chns = annot_signals; return(0); } int edf_set_datarecord_duration(int handle, int duration) { if(handle<0) { return(-1); } if(handle>=EDFLIB_MAXFILES) { return(-1); } if(hdrlist[handle]==NULL) { return(-1); } if(!(hdrlist[handle]->writemode)) { return(-1); } if(hdrlist[handle]->datarecords) { return(-1); } if((duration < 100) || (duration > 6000000)) { return(-1); } hdrlist[handle]->long_data_record_duration = (long long)duration * 100LL; if(hdrlist[handle]->long_data_record_duration < (EDFLIB_TIME_DIMENSION * 10LL)) { hdrlist[handle]->long_data_record_duration /= 10LL; hdrlist[handle]->long_data_record_duration *= 10LL; } else { hdrlist[handle]->long_data_record_duration /= 100LL; hdrlist[handle]->long_data_record_duration *= 100LL; } hdrlist[handle]->data_record_duration = ((double)(hdrlist[handle]->long_data_record_duration)) / EDFLIB_TIME_DIMENSION; return(0); } int edfwrite_digital_short_samples(int handle, short *buf) { int i, p, error, sf, digmax, digmin, edfsignal, value; FILE *file; struct edfhdrblock *hdr; if(handle<0) { return(-1); } if(handle>=EDFLIB_MAXFILES) { return(-1); } if(hdrlist[handle]==NULL) { return(-1); } if(!(hdrlist[handle]->writemode)) { return(-1); } if(hdrlist[handle]->edfsignals == 0) { return(-1); } if(hdrlist[handle]->bdf == 1) { return(-1); } hdr = hdrlist[handle]; file = hdr->file_hdl; edfsignal = hdr->signal_write_sequence_pos; if(!hdr->datarecords) { if(!edfsignal) { error = edflib_write_edf_header(hdr); if(error) { return(error); } } } sf = hdr->edfparam[edfsignal].smp_per_record; digmax = hdr->edfparam[edfsignal].dig_max; digmin = hdr->edfparam[edfsignal].dig_min; for(i=0; idigmax) { value = digmax; } if(value>8)&0xff, file)==EOF) { return(-1); } if(hdr->bdf) { fputc((value>>16)&0xff, file); } } hdr->signal_write_sequence_pos++; if(hdr->signal_write_sequence_pos == hdr->edfsignals) { hdr->signal_write_sequence_pos = 0; p = edflib_fprint_ll_number_nonlocalized(file, (hdr->datarecords * hdr->long_data_record_duration) / EDFLIB_TIME_DIMENSION, 0, 1); if(hdr->long_data_record_duration % EDFLIB_TIME_DIMENSION) { fputc('.', file); p++; p += edflib_fprint_ll_number_nonlocalized(file, (hdr->datarecords * hdr->long_data_record_duration) % EDFLIB_TIME_DIMENSION, 7, 0); } fputc(20, file); fputc(20, file); p += 2; for(; ptotal_annot_bytes; p++) { fputc(0, file); } hdr->datarecords++; fflush(file); } return(0); } int edfwrite_digital_samples(int handle, int *buf) { int i, p, error, sf, digmax, digmin, edfsignal, value; FILE *file; struct edfhdrblock *hdr; if(handle<0) { return(-1); } if(handle>=EDFLIB_MAXFILES) { return(-1); } if(hdrlist[handle]==NULL) { return(-1); } if(!(hdrlist[handle]->writemode)) { return(-1); } if(hdrlist[handle]->edfsignals == 0) { return(-1); } hdr = hdrlist[handle]; file = hdr->file_hdl; edfsignal = hdr->signal_write_sequence_pos; if(!hdr->datarecords) { if(!edfsignal) { error = edflib_write_edf_header(hdr); if(error) { return(error); } } } sf = hdr->edfparam[edfsignal].smp_per_record; digmax = hdr->edfparam[edfsignal].dig_max; digmin = hdr->edfparam[edfsignal].dig_min; for(i=0; idigmax) { value = digmax; } if(value>8)&0xff, file)==EOF) { return(-1); } if(hdr->bdf) { fputc((value>>16)&0xff, file); } } hdr->signal_write_sequence_pos++; if(hdr->signal_write_sequence_pos == hdr->edfsignals) { hdr->signal_write_sequence_pos = 0; p = edflib_fprint_ll_number_nonlocalized(file, (hdr->datarecords * hdr->long_data_record_duration) / EDFLIB_TIME_DIMENSION, 0, 1); if(hdr->long_data_record_duration % EDFLIB_TIME_DIMENSION) { fputc('.', file); p++; p += edflib_fprint_ll_number_nonlocalized(file, (hdr->datarecords * hdr->long_data_record_duration) % EDFLIB_TIME_DIMENSION, 7, 0); } fputc(20, file); fputc(20, file); p += 2; for(; ptotal_annot_bytes; p++) { fputc(0, file); } hdr->datarecords++; fflush(file); } return(0); } int edf_blockwrite_digital_samples(int handle, int *buf) { int i, j, p, error, sf, digmax, digmin, edfsignals, buf_offset, value; FILE *file; struct edfhdrblock *hdr; if(handle<0) { return(-1); } if(handle>=EDFLIB_MAXFILES) { return(-1); } if(hdrlist[handle]==NULL) { return(-1); } if(!(hdrlist[handle]->writemode)) { return(-1); } if(hdrlist[handle]->signal_write_sequence_pos) { return(-1); } if(hdrlist[handle]->edfsignals == 0) { return(-1); } hdr = hdrlist[handle]; file = hdr->file_hdl; edfsignals = hdr->edfsignals; if(!hdr->datarecords) { error = edflib_write_edf_header(hdr); if(error) { return(error); } } buf_offset = 0; for(j=0; jedfparam[j].smp_per_record; digmax = hdr->edfparam[j].dig_max; digmin = hdr->edfparam[j].dig_min; for(i=0; idigmax) { value = digmax; } if(value>8)&0xff, file)==EOF) { return(-1); } if(hdr->bdf) { fputc((value>>16)&0xff, file); } } buf_offset += sf; } p = edflib_fprint_ll_number_nonlocalized(file, (hdr->datarecords * hdr->long_data_record_duration) / EDFLIB_TIME_DIMENSION, 0, 1); if(hdr->long_data_record_duration % EDFLIB_TIME_DIMENSION) { fputc('.', file); p++; p += edflib_fprint_ll_number_nonlocalized(file, (hdr->datarecords * hdr->long_data_record_duration) % EDFLIB_TIME_DIMENSION, 7, 0); } fputc(20, file); fputc(20, file); p += 2; for(; ptotal_annot_bytes; p++) { fputc(0, file); } hdr->datarecords++; fflush(file); return(0); } int edf_blockwrite_digital_short_samples(int handle, short *buf) { int i, j, p, error, sf, digmax, digmin, edfsignals, buf_offset, value; FILE *file; struct edfhdrblock *hdr; if(handle<0) { return(-1); } if(handle>=EDFLIB_MAXFILES) { return(-1); } if(hdrlist[handle]==NULL) { return(-1); } if(!(hdrlist[handle]->writemode)) { return(-1); } if(hdrlist[handle]->signal_write_sequence_pos) { return(-1); } if(hdrlist[handle]->edfsignals == 0) { return(-1); } if(hdrlist[handle]->bdf == 1) { return(-1); } hdr = hdrlist[handle]; file = hdr->file_hdl; edfsignals = hdr->edfsignals; if(!hdr->datarecords) { error = edflib_write_edf_header(hdr); if(error) { return(error); } } buf_offset = 0; for(j=0; jedfparam[j].smp_per_record; digmax = hdr->edfparam[j].dig_max; digmin = hdr->edfparam[j].dig_min; for(i=0; idigmax) { value = digmax; } if(value>8)&0xff, file)==EOF) { return(-1); } if(hdr->bdf) { fputc((value>>16)&0xff, file); } } buf_offset += sf; } p = edflib_fprint_ll_number_nonlocalized(file, (hdr->datarecords * hdr->long_data_record_duration) / EDFLIB_TIME_DIMENSION, 0, 1); if(hdr->long_data_record_duration % EDFLIB_TIME_DIMENSION) { fputc('.', file); p++; p += edflib_fprint_ll_number_nonlocalized(file, (hdr->datarecords * hdr->long_data_record_duration) % EDFLIB_TIME_DIMENSION, 7, 0); } fputc(20, file); fputc(20, file); p += 2; for(; ptotal_annot_bytes; p++) { fputc(0, file); } hdr->datarecords++; fflush(file); return(0); } int edf_blockwrite_digital_3byte_samples(int handle, void *buf) { int j, p, error, edfsignals, total_samples=0; FILE *file; struct edfhdrblock *hdr; if(handle<0) { return(-1); } if(handle>=EDFLIB_MAXFILES) { return(-1); } if(hdrlist[handle]==NULL) { return(-1); } if(!(hdrlist[handle]->writemode)) { return(-1); } if(hdrlist[handle]->signal_write_sequence_pos) { return(-1); } if(hdrlist[handle]->edfsignals == 0) { return(-1); } if(hdrlist[handle]->bdf != 1) { return(-1); } hdr = hdrlist[handle]; file = hdr->file_hdl; edfsignals = hdr->edfsignals; if(!hdr->datarecords) { error = edflib_write_edf_header(hdr); if(error) { return(error); } } for(j=0; jedfparam[j].smp_per_record; } if(fwrite(buf, total_samples * 3, 1, file) != 1) { return(-1); } p = edflib_fprint_ll_number_nonlocalized(file, (hdr->datarecords * hdr->long_data_record_duration) / EDFLIB_TIME_DIMENSION, 0, 1); if(hdr->long_data_record_duration % EDFLIB_TIME_DIMENSION) { fputc('.', file); p++; p += edflib_fprint_ll_number_nonlocalized(file, (hdr->datarecords * hdr->long_data_record_duration) % EDFLIB_TIME_DIMENSION, 7, 0); } fputc(20, file); fputc(20, file); p += 2; for(; ptotal_annot_bytes; p++) { fputc(0, file); } hdr->datarecords++; fflush(file); return(0); } int edfwrite_physical_samples(int handle, double *buf) { int i, p, error, sf, digmax, digmin, value, edfsignal; double bitvalue, phys_offset; FILE *file; struct edfhdrblock *hdr; if(handle<0) { return(-1); } if(handle>=EDFLIB_MAXFILES) { return(-1); } if(hdrlist[handle]==NULL) { return(-1); } if(!(hdrlist[handle]->writemode)) { return(-1); } if(hdrlist[handle]->edfsignals == 0) { return(-1); } hdr = hdrlist[handle]; file = hdr->file_hdl; edfsignal = hdr->signal_write_sequence_pos; if(!hdr->datarecords) { if(!edfsignal) { error = edflib_write_edf_header(hdr); if(error) { return(error); } } } sf = hdr->edfparam[edfsignal].smp_per_record; digmax = hdr->edfparam[edfsignal].dig_max; digmin = hdr->edfparam[edfsignal].dig_min; bitvalue = hdr->edfparam[edfsignal].bitvalue; phys_offset = hdr->edfparam[edfsignal].offset; for(i=0; idigmax) { value = digmax; } if(value>8)&0xff, file)==EOF) { return(-1); } if(hdr->bdf) { fputc((value>>16)&0xff, file); } } hdr->signal_write_sequence_pos++; if(hdr->signal_write_sequence_pos == hdr->edfsignals) { hdr->signal_write_sequence_pos = 0; p = edflib_fprint_ll_number_nonlocalized(file, (hdr->datarecords * hdr->long_data_record_duration) / EDFLIB_TIME_DIMENSION, 0, 1); if(hdr->long_data_record_duration % EDFLIB_TIME_DIMENSION) { fputc('.', file); p++; p += edflib_fprint_ll_number_nonlocalized(file, (hdr->datarecords * hdr->long_data_record_duration) % EDFLIB_TIME_DIMENSION, 7, 0); } fputc(20, file); fputc(20, file); p += 2; for(; ptotal_annot_bytes; p++) { fputc(0, file); } hdr->datarecords++; fflush(file); } return(0); } int edf_blockwrite_physical_samples(int handle, double *buf) { int i, j, p, error, sf, digmax, digmin, edfsignals, buf_offset, value; double bitvalue, phys_offset; FILE *file; struct edfhdrblock *hdr; if(handle<0) { return(-1); } if(handle>=EDFLIB_MAXFILES) { return(-1); } if(hdrlist[handle]==NULL) { return(-1); } if(!(hdrlist[handle]->writemode)) { return(-1); } if(hdrlist[handle]->signal_write_sequence_pos) { return(-1); } if(hdrlist[handle]->edfsignals == 0) { return(-1); } hdr = hdrlist[handle]; file = hdr->file_hdl; edfsignals = hdr->edfsignals; if(!hdr->datarecords) { error = edflib_write_edf_header(hdr); if(error) { return(error); } } buf_offset = 0; for(j=0; jedfparam[j].smp_per_record; digmax = hdr->edfparam[j].dig_max; digmin = hdr->edfparam[j].dig_min; bitvalue = hdr->edfparam[j].bitvalue; phys_offset = hdr->edfparam[j].offset; for(i=0; idigmax) { value = digmax; } if(value>8)&0xff, file)==EOF) { return(-1); } if(hdr->bdf) { fputc((value>>16)&0xff, file); } } buf_offset += sf; } p = edflib_fprint_ll_number_nonlocalized(file, (hdr->datarecords * hdr->long_data_record_duration) / EDFLIB_TIME_DIMENSION, 0, 1); if(hdr->long_data_record_duration % EDFLIB_TIME_DIMENSION) { fputc('.', file); p++; p += edflib_fprint_ll_number_nonlocalized(file, (hdr->datarecords * hdr->long_data_record_duration) % EDFLIB_TIME_DIMENSION, 7, 0); } fputc(20, file); fputc(20, file); p += 2; for(; ptotal_annot_bytes; p++) { fputc(0, file); } hdr->datarecords++; fflush(file); return(0); } int edflib_write_edf_header(struct edfhdrblock *hdr) { int i, j, p, q, len, rest, edfsignals; char str[128]; struct tm *date_time; time_t elapsed_time; FILE *file; file = hdr->file_hdl; edfsignals = hdr->edfsignals; if(edfsignals<0) { return(-20); } if(edfsignals>EDFLIB_MAXSIGNALS) { return(-21); } hdr->eq_sf = 1; for(i=0; iedfparam[i].smp_per_record<1) { return(-22); } if(hdr->edfparam[i].dig_max==hdr->edfparam[i].dig_min) { return(-23); } if(hdr->edfparam[i].dig_maxedfparam[i].dig_min) { return(-24); } if(hdr->edfparam[i].phys_max==hdr->edfparam[i].phys_min) { return(-25); } if(i > 0) { if(hdr->edfparam[i].smp_per_record != hdr->edfparam[i-1].smp_per_record) { hdr->eq_sf = 0; } } } for(i=0; iedfparam[i].bitvalue = (hdr->edfparam[i].phys_max - hdr->edfparam[i].phys_min) / (hdr->edfparam[i].dig_max - hdr->edfparam[i].dig_min); hdr->edfparam[i].offset = hdr->edfparam[i].phys_max / hdr->edfparam[i].bitvalue - hdr->edfparam[i].dig_max; } rewind(file); if(hdr->edf) { fprintf(file, "0 "); } else { fputc(255, file); fprintf(file, "BIOSEMI"); } p = 0; if(hdr->plus_birthdate[0]==0) { rest = 72; } else { rest = 62; } len = strlen(hdr->plus_patientcode); if(len && rest) { if(len>rest) { len = rest; rest = 0; } else { rest -= len; } strcpy(str, hdr->plus_patientcode); edflib_latin1_to_ascii(str, len); str[len] = 0; for(i=0; iplus_gender[0]=='M') { fputc('M', file); } else { if(hdr->plus_gender[0]=='F') { fputc('F', file); } else { fputc('X', file); } } fputc(' ', file); p +=2; if(hdr->plus_birthdate[0]==0) { fputc('X', file); fputc(' ', file); p +=2; } else { fputc(hdr->plus_birthdate[0], file); fputc(hdr->plus_birthdate[1], file); fputc('-', file); q = edflib_atof_nonlocalized(&(hdr->plus_birthdate[3])); switch(q) { case 1: fprintf(file, "JAN"); break; case 2: fprintf(file, "FEB"); break; case 3: fprintf(file, "MAR"); break; case 4: fprintf(file, "APR"); break; case 5: fprintf(file, "MAY"); break; case 6: fprintf(file, "JUN"); break; case 7: fprintf(file, "JUL"); break; case 8: fprintf(file, "AUG"); break; case 9: fprintf(file, "SEP"); break; case 10: fprintf(file, "OCT"); break; case 11: fprintf(file, "NOV"); break; case 12: fprintf(file, "DEC"); break; } fputc('-', file); fputc(hdr->plus_birthdate[6], file); fputc(hdr->plus_birthdate[7], file); fputc(hdr->plus_birthdate[8], file); fputc(hdr->plus_birthdate[9], file); fputc(' ', file); p += 12; } len = strlen(hdr->plus_patient_name); if(len && rest) { if(len>rest) { len = rest; rest = 0; } else { rest -= len; } strcpy(str, hdr->plus_patient_name); edflib_latin1_to_ascii(str, len); str[len] = 0; for(i=0; iplus_patient_additional); if(len && rest) { if(len>rest) { len = rest; } strcpy(str, hdr->plus_patient_additional); edflib_latin1_to_ascii(str, len); str[len] = 0; p += fprintf(file, "%s", str); } for(; p<80; p++) { fputc(' ', file); } if(!hdr->startdate_year) { elapsed_time = time(NULL); date_time = localtime(&elapsed_time); hdr->startdate_year = date_time->tm_year + 1900; hdr->startdate_month = date_time->tm_mon + 1; hdr->startdate_day = date_time->tm_mday; hdr->starttime_hour = date_time->tm_hour; hdr->starttime_minute = date_time->tm_min; hdr->starttime_second = date_time->tm_sec % 60; } p = 0; p += fprintf(file, "Startdate %02u-", hdr->startdate_day); switch(hdr->startdate_month) { case 1 : fprintf(file, "JAN"); break; case 2 : fprintf(file, "FEB"); break; case 3 : fprintf(file, "MAR"); break; case 4 : fprintf(file, "APR"); break; case 5 : fprintf(file, "MAY"); break; case 6 : fprintf(file, "JUN"); break; case 7 : fprintf(file, "JUL"); break; case 8 : fprintf(file, "AUG"); break; case 9 : fprintf(file, "SEP"); break; case 10 : fprintf(file, "OCT"); break; case 11 : fprintf(file, "NOV"); break; case 12 : fprintf(file, "DEC"); break; } p += 3; fputc('-', file); p++; p += edflib_fprint_int_number_nonlocalized(file, hdr->startdate_year, 4, 0); fputc(' ', file); p++; rest = 42; len = strlen(hdr->plus_admincode); if(len && rest) { if(len>rest) { len = rest; rest = 0; } else { rest -= len; } strcpy(str, hdr->plus_admincode); edflib_latin1_to_ascii(str, len); str[len] = 0; for(i=0; iplus_technician); if(len && rest) { if(len>rest) { len = rest; rest = 0; } else { rest -= len; } strcpy(str, hdr->plus_technician); edflib_latin1_to_ascii(str, len); str[len] = 0; for(i=0; iplus_equipment); if(len && rest) { if(len>rest) { len = rest; rest = 0; } else { rest -= len; } strcpy(str, hdr->plus_equipment); edflib_latin1_to_ascii(str, len); str[len] = 0; for(i=0; iplus_recording_additional); if(len && rest) { if(len>rest) { len = rest; } strcpy(str, hdr->plus_recording_additional); edflib_latin1_to_ascii(str, len); str[len] = 0; p += fprintf(file, "%s", str); } for(; p<80; p++) { fputc(' ', file); } fprintf(file, "%02u.%02u.%02u", hdr->startdate_day, hdr->startdate_month, (hdr->startdate_year % 100)); fprintf(file, "%02u.%02u.%02u", hdr->starttime_hour, hdr->starttime_minute, hdr->starttime_second); p = edflib_fprint_int_number_nonlocalized(file, (edfsignals + hdr->nr_annot_chns + 1) * 256, 0, 0); for(; p<8; p++) { fputc(' ', file); } if(hdr->edf) { fprintf(file, "EDF+C"); } else { fprintf(file, "BDF+C"); } for(i=0; i<39; i++) { fputc(' ', file); } fprintf(file, "-1 "); if(hdr->long_data_record_duration == EDFLIB_TIME_DIMENSION) { fprintf(file, "1 "); } else { edflib_sprint_number_nonlocalized(str, hdr->data_record_duration); strcat(str, " "); str[8] = 0; fprintf(file, "%s", str); } p = edflib_fprint_int_number_nonlocalized(file, edfsignals + hdr->nr_annot_chns, 0, 0); for(; p<4; p++) { fputc(' ', file); } for(i=0; iedfparam[i].label); edflib_latin1_to_ascii(hdr->edfparam[i].label, len); for(j=0; jedfparam[i].label[j], file); } for(; j<16; j++) { fputc(' ', file); } } for(j=0; jnr_annot_chns; j++) { if(hdr->edf) { fprintf(file, "EDF Annotations "); } else { fprintf(file, "BDF Annotations "); } } for(i=0; iedfparam[i].transducer); edflib_latin1_to_ascii(hdr->edfparam[i].transducer, len); for(j=0; jedfparam[i].transducer[j], file); } for(; j<80; j++) { fputc(' ', file); } } for(j=0; jnr_annot_chns; j++) { for(i=0; i<80; i++) { fputc(' ', file); } } for(i=0; iedfparam[i].physdimension); edflib_latin1_to_ascii(hdr->edfparam[i].physdimension, len); for(j=0; jedfparam[i].physdimension[j], file); } for(; j<8; j++) { fputc(' ', file); } } for(j=0; jnr_annot_chns; j++) { fprintf(file, " "); } for(i=0; iedfparam[i].phys_min); for(; p<8; p++) { str[p] = ' '; } str[8] = 0; fprintf(file, "%s", str); } for(j=0; jnr_annot_chns; j++) { fprintf(file, "-1 "); } for(i=0; iedfparam[i].phys_max); for(; p<8; p++) { str[p] = ' '; } str[8] = 0; fprintf(file, "%s", str); } for(j=0; jnr_annot_chns; j++) { fprintf(file, "1 "); } for(i=0; iedfparam[i].dig_min, 0, 0); for(; p<8; p++) { fputc(' ', file); } } for(j=0; jnr_annot_chns; j++) { if(hdr->edf) { fprintf(file, "-32768 "); } else { fprintf(file, "-8388608"); } } for(i=0; iedfparam[i].dig_max, 0, 0); for(; p<8; p++) { fputc(' ', file); } } for(j=0; jnr_annot_chns; j++) { if(hdr->edf) { fprintf(file, "32767 "); } else { fprintf(file, "8388607 "); } } for(i=0; iedfparam[i].prefilter); edflib_latin1_to_ascii(hdr->edfparam[i].prefilter, len); for(j=0; jedfparam[i].prefilter[j], file); } for(; j<80; j++) { fputc(' ', file); } } for(i=0; inr_annot_chns; i++) { for(j=0; j<80; j++) { fputc(' ', file); } } for(i=0; iedfparam[i].smp_per_record, 0, 0); for(; p<8; p++) { fputc(' ', file); } } for(j=0; jnr_annot_chns; j++) { if(hdr->edf) { p = edflib_fprint_int_number_nonlocalized(file, EDFLIB_ANNOTATION_BYTES / 2, 0, 0); for(; p<8; p++) { fputc(' ', file); } } else { p = edflib_fprint_int_number_nonlocalized(file, EDFLIB_ANNOTATION_BYTES / 3, 0, 0); for(; p<8; p++) { fputc(' ', file); } } } for(i=0; i<(edfsignals * 32); i++) { fputc(' ', file); } for(i=0; i<(hdr->nr_annot_chns * 32); i++) { fputc(' ', file); } hdr->total_annot_bytes = EDFLIB_ANNOTATION_BYTES * hdr->nr_annot_chns; return(0); } int edf_set_label(int handle, int edfsignal, const char *label) { if(handle<0) { return(-1); } if(handle>=EDFLIB_MAXFILES) { return(-1); } if(hdrlist[handle]==NULL) { return(-1); } if(!(hdrlist[handle]->writemode)) { return(-1); } if(edfsignal<0) { return(-1); } if(edfsignal>=hdrlist[handle]->edfsignals) { return(-1); } if(hdrlist[handle]->datarecords) { return(-1); } strncpy(hdrlist[handle]->edfparam[edfsignal].label, label, 16); hdrlist[handle]->edfparam[edfsignal].label[16] = 0; edflib_remove_padding_trailing_spaces(hdrlist[handle]->edfparam[edfsignal].label); return(0); } int edf_set_physical_dimension(int handle, int edfsignal, const char *phys_dim) { if(handle<0) { return(-1); } if(handle>=EDFLIB_MAXFILES) { return(-1); } if(hdrlist[handle]==NULL) { return(-1); } if(!(hdrlist[handle]->writemode)) { return(-1); } if(edfsignal<0) { return(-1); } if(edfsignal>=hdrlist[handle]->edfsignals) { return(-1); } if(hdrlist[handle]->datarecords) { return(-1); } strncpy(hdrlist[handle]->edfparam[edfsignal].physdimension, phys_dim, 8); hdrlist[handle]->edfparam[edfsignal].physdimension[8] = 0; edflib_remove_padding_trailing_spaces(hdrlist[handle]->edfparam[edfsignal].physdimension); return(0); } int edf_set_physical_maximum(int handle, int edfsignal, double phys_max) { if(handle<0) { return(-1); } if(handle>=EDFLIB_MAXFILES) { return(-1); } if(hdrlist[handle]==NULL) { return(-1); } if(!(hdrlist[handle]->writemode)) { return(-1); } if(edfsignal<0) { return(-1); } if(edfsignal>=hdrlist[handle]->edfsignals) { return(-1); } if(hdrlist[handle]->datarecords) { return(-1); } hdrlist[handle]->edfparam[edfsignal].phys_max = phys_max; return(0); } int edf_set_physical_minimum(int handle, int edfsignal, double phys_min) { if(handle<0) { return(-1); } if(handle>=EDFLIB_MAXFILES) { return(-1); } if(hdrlist[handle]==NULL) { return(-1); } if(!(hdrlist[handle]->writemode)) { return(-1); } if(edfsignal<0) { return(-1); } if(edfsignal>=hdrlist[handle]->edfsignals) { return(-1); } if(hdrlist[handle]->datarecords) { return(-1); } hdrlist[handle]->edfparam[edfsignal].phys_min = phys_min; return(0); } int edf_set_digital_maximum(int handle, int edfsignal, int dig_max) { if(handle<0) { return(-1); } if(handle>=EDFLIB_MAXFILES) { return(-1); } if(hdrlist[handle]==NULL) { return(-1); } if(!(hdrlist[handle]->writemode)) { return(-1); } if(edfsignal<0) { return(-1); } if(edfsignal>=hdrlist[handle]->edfsignals) { return(-1); } if(hdrlist[handle]->edf) { if(dig_max > 32767) { return(-1); } } else { if(dig_max > 8388607) { return(-1); } } if(hdrlist[handle]->datarecords) { return(-1); } hdrlist[handle]->edfparam[edfsignal].dig_max = dig_max; return(0); } int edf_set_digital_minimum(int handle, int edfsignal, int dig_min) { if(handle<0) { return(-1); } if(handle>=EDFLIB_MAXFILES) { return(-1); } if(hdrlist[handle]==NULL) { return(-1); } if(!(hdrlist[handle]->writemode)) { return(-1); } if(edfsignal<0) { return(-1); } if(edfsignal>=hdrlist[handle]->edfsignals) { return(-1); } if(hdrlist[handle]->edf) { if(dig_min < (-32768)) { return(-1); } } else { if(dig_min < (-8388608)) { return(-1); } } if(hdrlist[handle]->datarecords) { return(-1); } hdrlist[handle]->edfparam[edfsignal].dig_min = dig_min; return(0); } int edf_set_patientname(int handle, const char *patientname) { if(handle<0) { return(-1); } if(handle>=EDFLIB_MAXFILES) { return(-1); } if(hdrlist[handle]==NULL) { return(-1); } if(!(hdrlist[handle]->writemode)) { return(-1); } if(hdrlist[handle]->datarecords) { return(-1); } strncpy(hdrlist[handle]->plus_patient_name, patientname, 80); hdrlist[handle]->plus_patient_name[80] = 0; edflib_remove_padding_trailing_spaces(hdrlist[handle]->plus_patient_name); return(0); } int edf_set_patientcode(int handle, const char *patientcode) { if(handle<0) { return(-1); } if(handle>=EDFLIB_MAXFILES) { return(-1); } if(hdrlist[handle]==NULL) { return(-1); } if(!(hdrlist[handle]->writemode)) { return(-1); } if(hdrlist[handle]->datarecords) { return(-1); } strncpy(hdrlist[handle]->plus_patientcode, patientcode, 80); hdrlist[handle]->plus_patientcode[80] = 0; edflib_remove_padding_trailing_spaces(hdrlist[handle]->plus_patientcode); return(0); } int edf_set_gender(int handle, int gender) { if(handle<0) { return(-1); } if(handle>=EDFLIB_MAXFILES) { return(-1); } if(hdrlist[handle]==NULL) { return(-1); } if(!(hdrlist[handle]->writemode)) { return(-1); } if(hdrlist[handle]->datarecords) { return(-1); } if((gender<0)||(gender>1)) { return(-1); } if(gender) { hdrlist[handle]->plus_gender[0] = 'M'; } else { hdrlist[handle]->plus_gender[0] = 'F'; } hdrlist[handle]->plus_gender[1] = 0; return(0); } int edf_set_birthdate(int handle, int birthdate_year, int birthdate_month, int birthdate_day) { if(handle<0) { return(-1); } if(handle>=EDFLIB_MAXFILES) { return(-1); } if(hdrlist[handle]==NULL) { return(-1); } if(!(hdrlist[handle]->writemode)) { return(-1); } if(hdrlist[handle]->datarecords) { return(-1); } if((birthdate_year<1800) || (birthdate_year>3000) || (birthdate_month<1) || (birthdate_month>12) || (birthdate_day<1) || (birthdate_day>31)) { return(-1); } sprintf(hdrlist[handle]->plus_birthdate, "%02i.%02i.%02i%02i", birthdate_day, birthdate_month, birthdate_year / 100, birthdate_year % 100); hdrlist[handle]->plus_birthdate[10] = 0; return(0); } int edf_set_patient_additional(int handle, const char *patient_additional) { if(handle<0) { return(-1); } if(handle>=EDFLIB_MAXFILES) { return(-1); } if(hdrlist[handle]==NULL) { return(-1); } if(!(hdrlist[handle]->writemode)) { return(-1); } if(hdrlist[handle]->datarecords) { return(-1); } strncpy(hdrlist[handle]->plus_patient_additional, patient_additional, 80); hdrlist[handle]->plus_patient_additional[80] = 0; edflib_remove_padding_trailing_spaces(hdrlist[handle]->plus_patient_additional); return(0); } int edf_set_admincode(int handle, const char *admincode) { if(handle<0) { return(-1); } if(handle>=EDFLIB_MAXFILES) { return(-1); } if(hdrlist[handle]==NULL) { return(-1); } if(!(hdrlist[handle]->writemode)) { return(-1); } if(hdrlist[handle]->datarecords) { return(-1); } strncpy(hdrlist[handle]->plus_admincode, admincode, 80); hdrlist[handle]->plus_admincode[80] = 0; edflib_remove_padding_trailing_spaces(hdrlist[handle]->plus_admincode); return(0); } int edf_set_technician(int handle, const char *technician) { if(handle<0) { return(-1); } if(handle>=EDFLIB_MAXFILES) { return(-1); } if(hdrlist[handle]==NULL) { return(-1); } if(!(hdrlist[handle]->writemode)) { return(-1); } if(hdrlist[handle]->datarecords) { return(-1); } strncpy(hdrlist[handle]->plus_technician, technician, 80); hdrlist[handle]->plus_technician[80] = 0; edflib_remove_padding_trailing_spaces(hdrlist[handle]->plus_technician); return(0); } int edf_set_equipment(int handle, const char *equipment) { if(handle<0) { return(-1); } if(handle>=EDFLIB_MAXFILES) { return(-1); } if(hdrlist[handle]==NULL) { return(-1); } if(!(hdrlist[handle]->writemode)) { return(-1); } if(hdrlist[handle]->datarecords) { return(-1); } strncpy(hdrlist[handle]->plus_equipment, equipment, 80); hdrlist[handle]->plus_equipment[80] = 0; edflib_remove_padding_trailing_spaces(hdrlist[handle]->plus_equipment); return(0); } int edf_set_recording_additional(int handle, const char *recording_additional) { if(handle<0) { return(-1); } if(handle>=EDFLIB_MAXFILES) { return(-1); } if(hdrlist[handle]==NULL) { return(-1); } if(!(hdrlist[handle]->writemode)) { return(-1); } if(hdrlist[handle]->datarecords) { return(-1); } strncpy(hdrlist[handle]->plus_recording_additional, recording_additional, 80); hdrlist[handle]->plus_recording_additional[80] = 0; edflib_remove_padding_trailing_spaces(hdrlist[handle]->plus_recording_additional); return(0); } int edf_set_startdatetime(int handle, int startdate_year, int startdate_month, int startdate_day, int starttime_hour, int starttime_minute, int starttime_second) { if(handle<0) { return(-1); } if(handle>=EDFLIB_MAXFILES) { return(-1); } if(hdrlist[handle]==NULL) { return(-1); } if(!(hdrlist[handle]->writemode)) { return(-1); } if(hdrlist[handle]->datarecords) { return(-1); } if((startdate_year<1970) || (startdate_year>3000) || (startdate_month<1) || (startdate_month>12) || (startdate_day<1) || (startdate_day>31) || (starttime_hour<0) || (starttime_hour>23) || (starttime_minute<0) || (starttime_minute>59) || (starttime_second<0) || (starttime_second>59)) { return(-1); } hdrlist[handle]->startdate_year = startdate_year; hdrlist[handle]->startdate_month = startdate_month; hdrlist[handle]->startdate_day = startdate_day; hdrlist[handle]->starttime_hour = starttime_hour; hdrlist[handle]->starttime_minute = starttime_minute; hdrlist[handle]->starttime_second = starttime_second; return(0); } int edfwrite_annotation_utf8(int handle, long long onset, long long duration, const char *description) { int i; struct edf_write_annotationblock *list_annot, *tmp_annot; if(handle<0) { return(-1); } if(handle>=EDFLIB_MAXFILES) { return(-1); } if(hdrlist[handle]==NULL) { return(-1); } if(!(hdrlist[handle]->writemode)) { return(-1); } if(onset<0LL) { return(-1); } list_annot = (struct edf_write_annotationblock *)calloc(1, sizeof(struct edf_write_annotationblock)); if(list_annot==NULL) { return(-1); } list_annot->onset = onset; list_annot->duration = duration; strncpy(list_annot->annotation, description, EDFLIB_WRITE_MAX_ANNOTATION_LEN); list_annot->annotation[EDFLIB_WRITE_MAX_ANNOTATION_LEN] = 0; list_annot->next_annotation = NULL; list_annot->former_annotation = NULL; for(i=0; ; i++) { if(list_annot->annotation[i] == 0) { break; } if(list_annot->annotation[i] < 32) { list_annot->annotation[i] = '.'; } } if(write_annotationslist[handle]==NULL) { write_annotationslist[handle] = list_annot; } else { tmp_annot = write_annotationslist[handle]; while(tmp_annot->next_annotation!=NULL) { tmp_annot = tmp_annot->next_annotation; } tmp_annot->next_annotation = list_annot; list_annot->former_annotation = tmp_annot; } return(0); } int edfwrite_annotation_latin1(int handle, long long onset, long long duration, const char *description) { struct edf_write_annotationblock *list_annot, *tmp_annot; char str[EDFLIB_WRITE_MAX_ANNOTATION_LEN + 1]; if(handle<0) { return(-1); } if(handle>=EDFLIB_MAXFILES) { return(-1); } if(hdrlist[handle]==NULL) { return(-1); } if(!(hdrlist[handle]->writemode)) { return(-1); } if(onset<0LL) { return(-1); } list_annot = (struct edf_write_annotationblock *)calloc(1, sizeof(struct edf_write_annotationblock)); if(list_annot==NULL) { return(-1); } list_annot->onset = onset; list_annot->duration = duration; strncpy(str, description, EDFLIB_WRITE_MAX_ANNOTATION_LEN); str[EDFLIB_WRITE_MAX_ANNOTATION_LEN] = 0; edflib_latin12utf8(str, strlen(str)); strncpy(list_annot->annotation, str, EDFLIB_WRITE_MAX_ANNOTATION_LEN); list_annot->annotation[EDFLIB_WRITE_MAX_ANNOTATION_LEN] = 0; list_annot->next_annotation = NULL; list_annot->former_annotation = NULL; if(write_annotationslist[handle]==NULL) { write_annotationslist[handle] = list_annot; } else { tmp_annot = write_annotationslist[handle]; while(tmp_annot->next_annotation!=NULL) { tmp_annot = tmp_annot->next_annotation; } tmp_annot->next_annotation = list_annot; list_annot->former_annotation = tmp_annot; } return(0); } void edflib_remove_padding_trailing_spaces(char *str) { int i; while(str[0]==' ') { for(i=0; ; i++) { if(str[i]==0) { break; } str[i] = str[i+1]; } } for(i = strlen(str); i>0; i--) { if(str[i-1]==' ') { str[i-1] = 0; } else { break; } } } int edf_set_prefilter(int handle, int edfsignal, const char *prefilter) { if(handle<0) { return(-1); } if(handle>=EDFLIB_MAXFILES) { return(-1); } if(hdrlist[handle]==NULL) { return(-1); } if(!(hdrlist[handle]->writemode)) { return(-1); } if(edfsignal<0) { return(-1); } if(edfsignal>=hdrlist[handle]->edfsignals) { return(-1); } if(hdrlist[handle]->datarecords) { return(-1); } strncpy(hdrlist[handle]->edfparam[edfsignal].prefilter, prefilter, 80); hdrlist[handle]->edfparam[edfsignal].prefilter[80] = 0; edflib_remove_padding_trailing_spaces(hdrlist[handle]->edfparam[edfsignal].prefilter); return(0); } int edf_set_transducer(int handle, int edfsignal, const char *transducer) { if(handle<0) { return(-1); } if(handle>=EDFLIB_MAXFILES) { return(-1); } if(hdrlist[handle]==NULL) { return(-1); } if(!(hdrlist[handle]->writemode)) { return(-1); } if(edfsignal<0) { return(-1); } if(edfsignal>=hdrlist[handle]->edfsignals) { return(-1); } if(hdrlist[handle]->datarecords) { return(-1); } strncpy(hdrlist[handle]->edfparam[edfsignal].transducer, transducer, 80); hdrlist[handle]->edfparam[edfsignal].transducer[80] = 0; edflib_remove_padding_trailing_spaces(hdrlist[handle]->edfparam[edfsignal].transducer); return(0); } /* minimum is the minimum digits that will be printed (minus sign not included), leading zero's will be added if necessary */ /* if sign is zero, only negative numbers will have the sign '-' character */ /* if sign is one, the sign '+' or '-' character will always be printed */ /* returns the amount of characters printed */ int edflib_fprint_int_number_nonlocalized(FILE *file, int q, int minimum, int sign) { int flag=0, z, i, j=0, base = 1000000000; if(minimum < 0) { minimum = 0; } if(minimum > 9) { flag = 1; } if(q < 0) { fputc('-', file); j++; q = -q; } else { if(sign) { fputc('+', file); j++; } } for(i=10; i; i--) { if(minimum == i) { flag = 1; } z = q / base; q %= base; if(z || flag) { fputc('0' + z, file); j++; flag = 1; } base /= 10; } if(!flag) { fputc('0', file); j++; } return(j); } /* minimum is the minimum digits that will be printed (minus sign not included), leading zero's will be added if necessary */ /* if sign is zero, only negative numbers will have the sign '-' character */ /* if sign is one, the sign '+' or '-' character will always be printed */ /* returns the amount of characters printed */ int edflib_fprint_ll_number_nonlocalized(FILE *file, long long q, int minimum, int sign) { int flag=0, z, i, j=0; long long base = 1000000000000000000LL; if(minimum < 0) { minimum = 0; } if(minimum > 18) { flag = 1; } if(q < 0LL) { fputc('-', file); j++; q = -q; } else { if(sign) { fputc('+', file); j++; } } for(i=19; i; i--) { if(minimum == i) { flag = 1; } z = q / base; q %= base; if(z || flag) { fputc('0' + z, file); j++; flag = 1; } base /= 10LL; } if(!flag) { fputc('0', file); j++; } return(j); } /* minimum is the minimum digits that will be printed (minus sign not included), leading zero's will be added if necessary */ /* if sign is zero, only negative numbers will have the sign '-' character */ /* if sign is one, the sign '+' or '-' character will always be printed */ /* returns the amount of characters printed */ int edflib_sprint_int_number_nonlocalized(char *str, int q, int minimum, int sign) { int flag=0, z, i, j=0, base = 1000000000; if(minimum < 0) { minimum = 0; } if(minimum > 9) { flag = 1; } if(q < 0) { str[j++] = '-'; q = -q; } else { if(sign) { str[j++] = '+'; } } for(i=10; i; i--) { if(minimum == i) { flag = 1; } z = q / base; q %= base; if(z || flag) { str[j++] = '0' + z; flag = 1; } base /= 10; } if(!flag) { str[j++] = '0'; } str[j] = 0; return(j); } /* minimum is the minimum digits that will be printed (minus sign not included), leading zero's will be added if necessary */ /* if sign is zero, only negative numbers will have the sign '-' character */ /* if sign is one, the sign '+' or '-' character will always be printed */ /* returns the amount of characters printed */ int edflib_sprint_ll_number_nonlocalized(char *str, long long q, int minimum, int sign) { int flag=0, z, i, j=0; long long base = 1000000000000000000LL; if(minimum < 0) { minimum = 0; } if(minimum > 18) { flag = 1; } if(q < 0LL) { str[j++] = '-'; q = -q; } else { if(sign) { str[j++] = '+'; } } for(i=19; i; i--) { if(minimum == i) { flag = 1; } z = q / base; q %= base; if(z || flag) { str[j++] = '0' + z; flag = 1; } base /= 10LL; } if(!flag) { str[j++] = '0'; } str[j] = 0; return(j); } int edflib_sprint_number_nonlocalized(char *str, double nr) { int flag=0, z, i, j=0, q, base = 1000000000; double var; q = (int)nr; var = nr - q; if(nr < 0.0) { str[j++] = '-'; if(q < 0) { q = -q; } } for(i=10; i; i--) { z = q / base; q %= base; if(z || flag) { str[j++] = '0' + z; flag = 1; } base /= 10; } if(!flag) { str[j++] = '0'; } base = 100000000; var *= (base * 10); q = (int)var; if(q < 0) { q = -q; } if(!q) { str[j] = 0; return(j); } str[j++] = '.'; for(i=9; i; i--) { z = q / base; q %= base; str[j++] = '0' + z; base /= 10; } str[j] = 0; j--; for(; j>0; j--) { if(str[j] == '0') { str[j] = 0; } else { j++; break; } } return(j); } double edflib_atof_nonlocalized(const char *str) { int i=0, dot_pos=-1, decimals=0, sign=1; double value, value2=0.0; value = edflib_atoi_nonlocalized(str); while(str[i] == ' ') { i++; } if((str[i] == '+') || (str[i] == '-')) { if(str[i] == '-') { sign = -1; } i++; } for(; ; i++) { if(str[i] == 0) { break; } if(((str[i] < '0') || (str[i] > '9')) && (str[i] != '.')) { break; } if(dot_pos >= 0) { if((str[i] >= '0') && (str[i] <= '9')) { decimals++; } else { break; } } if(str[i] == '.') { if(dot_pos < 0) { dot_pos = i; } } } if(decimals) { value2 = edflib_atoi_nonlocalized(str + dot_pos + 1) * sign; i = 1; while(decimals--) { i *= 10; } value2 /= i; } return(value + value2); } int edflib_atoi_nonlocalized(const char *str) { int i=0, value=0, sign=1; while(str[i] == ' ') { i++; } if((str[i] == '+') || (str[i] == '-')) { if(str[i] == '-') { sign = -1; } i++; } for( ; ; i++) { if(str[i] == 0) { break; } if((str[i] < '0') || (str[i] > '9')) { break; } value *= 10; value += (str[i] - '0'); } return(value * sign); } edfbrowser_153_source/PaxHeaders.2978/show_actual_montage_dialog.h0000644000175000001440000000013212251654530023662 xustar000000000000000030 mtime=1386699096.468032569 30 atime=1386699096.468032569 30 ctime=1386699096.468032569 edfbrowser_153_source/show_actual_montage_dialog.h0000644000175000001440000000362212251654530023416 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef SHOWACTUALMONTAGEFORM1_H #define SHOWACTUALMONTAGEFORM1_H #include #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "mainwindow.h" #include "utils.h" class UI_Mainwindow; class UI_ShowActualMontagewindow : public QObject { Q_OBJECT public: UI_ShowActualMontagewindow(QWidget *parent); UI_Mainwindow *mainwindow; private: QDialog *ShowMontageDialog; QPushButton *CloseButton; QBoxLayout *box; QTreeView *tree; QStandardItemModel *t_model; }; #endif // SHOWACTUALMONTAGEFORM1_H edfbrowser_153_source/PaxHeaders.2978/popup_save_cancelwindow.cpp0000644000175000001440000000013212251654530023571 xustar000000000000000030 mtime=1386699096.478032517 30 atime=1386699096.478032517 30 ctime=1386699096.478032517 edfbrowser_153_source/popup_save_cancelwindow.cpp0000644000175000001440000000575212251654530023333 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "popup_save_cancelwindow.h" UI_CancelSavewindow::UI_CancelSavewindow(const char *title, const char *str, const char *button1txt, const char *button2txt, int *button_nr) { int i, len, max=0, labelwidth = 0, labelheight = 20; buttonnr = button_nr; len = strlen(str); for(i=0; ilabelwidth) labelwidth = max; max = 0; } else { max++; } } if(max>labelwidth) labelwidth = max; labelwidth *= 6; labelwidth += 10; if(labelwidth<260) labelwidth = 260; MessageDialog = new QDialog; MessageDialog->setMinimumSize(QSize(labelwidth + 40, labelheight + 85)); MessageDialog->setMaximumSize(QSize(labelwidth + 40, labelheight + 85)); MessageDialog->setWindowTitle(title); MessageDialog->setModal(TRUE); MessageDialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); Label1 = new QLabel(MessageDialog); Label1->setGeometry(20, 20, labelwidth, labelheight); Label1->setAlignment(Qt::AlignLeft | Qt::AlignTop); Label1->setText(str); pushButton1 = new QPushButton(MessageDialog); pushButton1->setGeometry(20, labelheight + 40, 100, 25); pushButton1->setText(button1txt); pushButton2 = new QPushButton(MessageDialog); pushButton2->setGeometry(140, labelheight + 40, 100, 25); pushButton2->setText(button2txt); QObject::connect(pushButton1, SIGNAL(clicked()), this, SLOT(button1Clicked())); QObject::connect(pushButton2, SIGNAL(clicked()), this, SLOT(button2Clicked())); MessageDialog->exec(); } void UI_CancelSavewindow::button1Clicked() { *buttonnr = 0; MessageDialog->close(); } void UI_CancelSavewindow::button2Clicked() { *buttonnr = 1; MessageDialog->close(); } edfbrowser_153_source/PaxHeaders.2978/ecg_export.cpp0000644000175000001440000000013212251654530021012 xustar000000000000000030 mtime=1386699096.477032522 30 atime=1386699096.477032522 30 ctime=1386699096.477032522 edfbrowser_153_source/ecg_export.cpp0000644000175000001440000002725212251654530020553 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "ecg_export.h" #if defined(__APPLE__) || defined(__MACH__) || defined(__APPLE_CC__) #define fopeno fopen #else #define fseeko fseeko64 #define ftello ftello64 #define fopeno fopen64 #endif UI_ECGExport::UI_ECGExport(QWidget *w_parent) { mainwindow = (UI_Mainwindow *)w_parent; myobjectDialog = new QDialog(w_parent); myobjectDialog->setMinimumSize(QSize(400, 445)); myobjectDialog->setMaximumSize(QSize(400, 445)); myobjectDialog->setWindowTitle("Export RR-intervals"); myobjectDialog->setModal(TRUE); myobjectDialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); list = new QListWidget(myobjectDialog); list->setGeometry(20, 20, 130, 350); list->setSelectionBehavior(QAbstractItemView::SelectRows); list->setSelectionMode(QAbstractItemView::SingleSelection); groupBox1 = new QGroupBox(myobjectDialog); groupBox1->setGeometry(170, 20, 210, 120); groupBox1->setTitle("Output format"); radioButton1 = new QRadioButton("RR interval"); radioButton2 = new QRadioButton("R Onset + RR interval"); radioButton3 = new QRadioButton("R Onset"); radioButton2->setChecked(TRUE); checkBox1 = new QCheckBox("Whole recording", myobjectDialog); checkBox1->setGeometry(170, 160, 210, 25); checkBox1->setTristate(FALSE); checkBox2 = new QCheckBox("Don't write to file,\n" "import as annotations instead", myobjectDialog); checkBox2->setGeometry(170, 200, 210, 40); checkBox2->setTristate(FALSE); vbox1 = new QVBoxLayout; vbox1->addWidget(radioButton1); vbox1->addWidget(radioButton2); vbox1->addWidget(radioButton3); groupBox1->setLayout(vbox1); startButton = new QPushButton(myobjectDialog); startButton->setGeometry(20, 400, 150, 25); startButton->setText("Import/Export"); cancelButton = new QPushButton(myobjectDialog); cancelButton->setGeometry(280, 400, 100, 25); cancelButton->setText("Cancel"); load_signalcomps(); QObject::connect(cancelButton, SIGNAL(clicked()), myobjectDialog, SLOT(close())); QObject::connect(startButton, SIGNAL(clicked()), this, SLOT(Export_RR_intervals())); myobjectDialog->exec(); } void UI_ECGExport::Export_RR_intervals() { int i, len, signal_nr, type=-1, beat_cnt, samples_cnt, progress_steps, datarecords, whole_recording=0, import_as_annots=0, filenum=0; char path[MAX_PATH_LENGTH], str[2048]; double *beat_interval_list, *buf; long long *beat_onset_list, datrecs, smpls_left, l_time=0LL; struct signalcompblock *signalcomp; FILE *outputfile; QList selectedlist; struct annotationblock *annotation; selectedlist = list->selectedItems(); if(selectedlist.size() < 1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Select a signal first."); messagewindow.exec(); return; } signal_nr = selectedlist.at(0)->data(Qt::UserRole).toInt(); if((signal_nr < 0) || (signal_nr >= mainwindow->signalcomps)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Invalid signalcomp number"); messagewindow.exec(); return; } signalcomp = mainwindow->signalcomp[signal_nr]; if(signalcomp->ecg_filter == NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Heart Rate detection is not activated for the selected signal."); messagewindow.exec(); return; } if(checkBox2->checkState() == Qt::Checked) { import_as_annots = 1; } if(checkBox1->checkState() == Qt::Checked) { whole_recording = 1; class FilteredBlockReadClass blockrd; buf = blockrd.init_signalcomp(signalcomp, 1, 0); if(buf == NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Error, can not initialize FilteredBlockReadClass."); messagewindow.exec(); return; } samples_cnt = blockrd.samples_in_buf(); if(samples_cnt < 1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Error, samples_cnt is < 1."); messagewindow.exec(); return; } filenum = signalcomp->filenum; reset_ecg_filter(signalcomp->ecg_filter); datarecords = signalcomp->edfhdr->datarecords; QProgressDialog progress("Processing file...", "Abort", 0, datarecords); progress.setWindowModality(Qt::WindowModal); progress.setMinimumDuration(200); progress_steps = datarecords / 100; if(progress_steps < 1) { progress_steps = 1; } for(i=0; iedfhdr->datarecords; i++) { if(!(i%progress_steps)) { progress.setValue(i); qApp->processEvents(); if(progress.wasCanceled() == TRUE) { return; } } if(blockrd.process_signalcomp(i) != 0) { progress.reset(); QMessageBox messagewindow(QMessageBox::Critical, "Error", "Error while reading file."); messagewindow.exec(); return; } } progress.reset(); } beat_cnt = ecg_filter_get_beat_cnt(signalcomp->ecg_filter); beat_onset_list = ecg_filter_get_onset_beatlist(signalcomp->ecg_filter); beat_interval_list = ecg_filter_get_interval_beatlist(signalcomp->ecg_filter); if(beat_cnt < 4) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Error, not enough beats."); messagewindow.exec(); return; } if(import_as_annots) { for(i=0; iedfhdr->viewtime; } if(l_time < 0LL) { l_time = 0LL; } datrecs = beat_onset_list[i] / signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].smp_per_record; smpls_left = beat_onset_list[i] % signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].smp_per_record; l_time += (datrecs * signalcomp->edfhdr->long_data_record_duration); l_time += ((smpls_left * signalcomp->edfhdr->long_data_record_duration) / signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].smp_per_record); if(!whole_recording) { l_time += (mainwindow->edfheaderlist[mainwindow->sel_viewtime]->viewtime - signalcomp->edfhdr->viewtime); } annotation = (struct annotationblock *)calloc(1, sizeof(struct annotationblock)); if(annotation == NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "A memory allocation error occurred (annotation)."); messagewindow.exec(); return; } annotation->onset = l_time; strncpy(annotation->annotation, "R-onset", MAX_ANNOTATION_LEN); annotation->annotation[MAX_ANNOTATION_LEN] = 0; edfplus_annotation_add_item(&mainwindow->annotationlist[filenum], annotation); } if(mainwindow->annotations_dock[signalcomp->filenum] == NULL) { mainwindow->annotations_dock[filenum] = new UI_Annotationswindow(filenum, mainwindow); mainwindow->addDockWidget(Qt::RightDockWidgetArea, mainwindow->annotations_dock[filenum]->docklist, Qt::Vertical); if(!mainwindow->annotationlist[filenum]) { mainwindow->annotations_dock[filenum]->docklist->hide(); } } if(mainwindow->annotationlist[filenum]) { mainwindow->annotations_dock[filenum]->docklist->show(); mainwindow->annotations_edited = 1; mainwindow->annotations_dock[filenum]->updateList(); mainwindow->save_act->setEnabled(TRUE); } } else { 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, signalcomp->edfhdr->filename, MAX_PATH_LENGTH - len); remove_extension_from_filename(path); strcat(path, "_RR_interval.txt"); strcpy(path, QFileDialog::getSaveFileName(0, "Export RR-interval to ASCII", QString::fromLocal8Bit(path), "Text files (*.txt *.TXT)").toLocal8Bit().data()); if(!strcmp(path, "")) { return; } get_directory_from_path(mainwindow->recent_savedir, path, MAX_PATH_LENGTH); outputfile = fopeno(path, "wb"); if(outputfile==NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Error, can not open outputfile for writing."); messagewindow.exec(); return; } if(radioButton1->isChecked() == TRUE) { type = 1; } if(radioButton2->isChecked() == TRUE) { type = 2; } if(radioButton3->isChecked() == TRUE) { type = 3; } if(type == 1) { for(i=0; iedfhdr->viewtime; } if(l_time < 0LL) { l_time = 0LL; } datrecs = beat_onset_list[i] / signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].smp_per_record; smpls_left = beat_onset_list[i] % signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].smp_per_record; l_time += (datrecs * signalcomp->edfhdr->long_data_record_duration); l_time += ((smpls_left * signalcomp->edfhdr->long_data_record_duration) / signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].smp_per_record); if(!whole_recording) { l_time += (mainwindow->edfheaderlist[mainwindow->sel_viewtime]->viewtime - signalcomp->edfhdr->viewtime); } if(type == 2) { fprintf(outputfile, "%.4f\t%.4f\n", ((double)l_time) / TIME_DIMENSION, beat_interval_list[i]); } if(type == 3) { fprintf(outputfile, "%.4f\n", ((double)l_time) / TIME_DIMENSION); } } } fclose(outputfile); } myobjectDialog->close(); if(!import_as_annots) { sprintf(str, "Done. The R-onsets and/or RR-intervals are exported to:\n\n%s", path); QMessageBox messagewindow(QMessageBox::Information, "Ready", QString::fromLocal8Bit(str)); messagewindow.setIconPixmap(QPixmap(":/images/ok.png")); messagewindow.exec(); } reset_ecg_filter(signalcomp->ecg_filter); mainwindow->setup_viewbuf(); } void UI_ECGExport::load_signalcomps(void) { int i; QListWidgetItem *item; list->clear(); for(i=0; isignalcomps; i++) { item = new QListWidgetItem; item->setText(mainwindow->signalcomp[i]->signallabel); item->setData(Qt::UserRole, QVariant(i)); list->addItem(item); } } edfbrowser_153_source/PaxHeaders.2978/flywheel.h0000644000175000001440000000013212251654530020137 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/flywheel.h0000644000175000001440000000457212251654530017700 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef FLYWHEELBUTTON_H #define FLYWHEELBUTTON_H #include #include #include #include #include #include #include #include #include class UI_Flywheel: public QWidget { Q_OBJECT public: UI_Flywheel(QWidget *parent=0); ~UI_Flywheel(); QSize sizeHint() const {return minimumSizeHint(); } QSize minimumSizeHint() const {return QSize(10,30); } private slots: void wheel_rotate(void); void t2_time_out(void); protected: void paintEvent(QPaintEvent *); void mousePressEvent(QMouseEvent *); void mouseReleaseEvent(QMouseEvent *); void mouseMoveEvent(QMouseEvent *); private: QTimer *t1, *t2; int mouse_y, mouse_old_y, mouse_delta_y, use_move_events, time_old, time_new, dial_speed, dial_speed_arr[4], dial_speed_ptr, spinning, holdoff, knobs, cursor_above_object; double wheel_position; struct timeval tv; QColor *bordercolor_up, *bordercolor_down; QLinearGradient *linearGrad; signals: void dialMoved(int); }; #endif edfbrowser_153_source/PaxHeaders.2978/manscan2edf.h0000644000175000001440000000013212251654530020501 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/manscan2edf.h0000644000175000001440000000513012251654530020231 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef UI_MANSCAN2EDFFORM_H #define UI_MANSCAN2EDFFORM_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "utils.h" #include "edflib.h" #include "utc_date_time.h" class UI_MANSCAN2EDFwindow : public QObject { Q_OBJECT public: UI_MANSCAN2EDFwindow(char *recent_dir=NULL, char *save_dir=NULL); private: QPushButton *pushButton1, *pushButton2; QTextEdit *textEdit1; QDialog *myobjectDialog; char *recent_opendir, *recent_savedir; int get_worddatafile(struct segment_prop_struct *, int, FILE *); int get_channel_gain(struct segment_prop_struct *, int, FILE *); int get_start_date(struct segment_prop_struct *, int, FILE *); int get_sample_rate(struct segment_prop_struct *, int, FILE *); int get_filter_settings(struct segment_prop_struct *, int, FILE *); int get_recorder_version(struct segment_prop_struct *, int, FILE *); int get_starttime_offset(struct segment_prop_struct *, int, FILE *); int get_events(struct segment_prop_struct *, int, FILE *); int get_number_of_segments(FILE *); char * fgetline(char *, int, FILE *); long long get_long_time(const char *); private slots: void SelectFileButton(); }; #endif edfbrowser_153_source/PaxHeaders.2978/nk2edf.h0000644000175000001440000000013212251654530017471 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/nk2edf.h0000644000175000001440000000415412251654530017226 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef UI_NK2EDFFORM_H #define UI_NK2EDFFORM_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "utils.h" class UI_NK2EDFwindow : public QObject { Q_OBJECT public: UI_NK2EDFwindow(char *recent_dir=NULL); private: QPushButton *pushButton1, *pushButton2; QTextEdit *textEdit1; QDialog *myobjectDialog; QCheckBox *checkBox1; int total_elapsed_time; char *recent_opendir, labels[256][17]; int check_device(char *); int read_21e_file(char *); private slots: void SelectFileButton(); int convert_nk2edf(FILE *, FILE *, FILE *, int, int, int, char *, int); }; #endif edfbrowser_153_source/PaxHeaders.2978/filter.h0000644000175000001440000000013212251654530017605 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/filter.h0000644000175000001440000000362712251654530017346 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef filter_INCLUDED #define filter_INCLUDED #include #include #include struct filter_settings{ double old_input; double old_output; double factor; double sample_frequency; double cutoff_frequency; int is_LPF; int first_sample; }; struct filter_settings * create_filter(int, double, double); void reset_filter(int, struct filter_settings *); int first_order_filter(int, struct filter_settings *); double get_filter_factor(double, double); struct filter_settings * create_filter_copy(struct filter_settings *); #endif edfbrowser_153_source/PaxHeaders.2978/wav2edf.cpp0000644000175000001440000000013212251654530020211 xustar000000000000000030 mtime=1386699096.479032511 30 atime=1386699096.479032511 30 ctime=1386699096.479032511 edfbrowser_153_source/wav2edf.cpp0000644000175000001440000004262012251654530017746 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "wav2edf.h" #if defined(__APPLE__) || defined(__MACH__) || defined(__APPLE_CC__) #define fopeno fopen #else #define fseeko fseeko64 #define ftello ftello64 #define fopeno fopen64 #endif UI_WAV2EDFwindow::UI_WAV2EDFwindow(char *recent_dir, char *save_dir) { recent_opendir = recent_dir; recent_savedir = save_dir; myobjectDialog = new QDialog; myobjectDialog->setMinimumSize(QSize(600, 300)); myobjectDialog->setMaximumSize(QSize(600, 300)); myobjectDialog->setWindowTitle("Wave to EDF converter"); myobjectDialog->setModal(TRUE); myobjectDialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); PatientnameLabel = new QLabel(myobjectDialog); PatientnameLabel->setGeometry(QRect(20, 20, 140, 16)); PatientnameLabel->setText("Subject"); RecordingLabel = new QLabel(myobjectDialog); RecordingLabel->setGeometry(QRect(20, 50, 140, 16)); RecordingLabel->setText("Recording"); DatetimeLabel = new QLabel(myobjectDialog); DatetimeLabel->setGeometry(QRect(20, 80, 140, 16)); DatetimeLabel->setText("Startdate and time"); PhysDimLabel = new QLabel(myobjectDialog); PhysDimLabel->setGeometry(QRect(20, 110, 140, 16)); PhysDimLabel->setText("Physical dimension"); PhysMaxLabel = new QLabel(myobjectDialog); PhysMaxLabel->setGeometry(QRect(20, 140, 140, 16)); PhysMaxLabel->setText("Physical maximum"); PatientnameLineEdit = new QLineEdit(myobjectDialog); PatientnameLineEdit->setGeometry(QRect(160, 20, 420, 21)); PatientnameLineEdit->setMaxLength(80); RecordingLineEdit = new QLineEdit(myobjectDialog); RecordingLineEdit->setGeometry(QRect(160, 50, 420, 21)); RecordingLineEdit->setMaxLength(80); StartDatetimeedit = new QDateTimeEdit(myobjectDialog); StartDatetimeedit->setGeometry(QRect(160, 80, 140, 22)); StartDatetimeedit->setDisplayFormat("dd/MM/yyyy hh:mm:ss"); StartDatetimeedit->setDateTime(QDateTime::currentDateTime()); PhysDimLineEdit = new QLineEdit(myobjectDialog); PhysDimLineEdit->setGeometry(QRect(160, 110, 140, 21)); PhysDimLineEdit->setMaxLength(8); PhysDimLineEdit->setText("mV"); PhysMaxSpinBox = new QDoubleSpinBox(myobjectDialog); PhysMaxSpinBox->setGeometry(QRect(160, 140, 140, 21)); PhysMaxSpinBox->setDecimals(5); PhysMaxSpinBox->setRange(1.0, 1000000.0); PhysMaxSpinBox->setValue(2000.0); pushButton1 = new QPushButton(myobjectDialog); pushButton1->setGeometry(QRect(20, 250, 100, 26)); pushButton1->setText("Select File"); pushButton2 = new QPushButton(myobjectDialog); pushButton2->setGeometry(QRect(480, 250, 100, 26)); pushButton2->setText("Close"); QObject::connect(pushButton1, SIGNAL(clicked()), this, SLOT(SelectFileButton())); QObject::connect(pushButton2, SIGNAL(clicked()), myobjectDialog, SLOT(close())); myobjectDialog->exec(); } 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 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 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; ivalue()); } for(i=0; ivalue() * -1.0); } for(i=0; itext().toLatin1().data()); } for(i=0; itext().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; kprocessEvents(); 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; isetEnabled(toggle); PatientnameLineEdit->setEnabled(toggle); RecordingLineEdit->setEnabled(toggle); pushButton1->setEnabled(toggle); pushButton2->setEnabled(toggle); } edfbrowser_153_source/PaxHeaders.2978/ravg_filter.h0000644000175000001440000000013212251654530020624 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/ravg_filter.h0000644000175000001440000000421012251654530020352 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef ravg_filter_INCLUDED #define ravg_filter_INCLUDED #include #include #include struct ravg_filter_settings{ int size; int type; int first_sample; double *buf; double *buf2; int buf_pntr; int buf_pntr2; double mean; double mean2; }; struct ravg_filter_settings * create_ravg_filter(int, int); void reset_ravg_filter(double, struct ravg_filter_settings *); double run_ravg_filter(double, struct ravg_filter_settings *); void free_ravg_filter(struct ravg_filter_settings *); void ravg_filter_restore_buf(struct ravg_filter_settings *); void ravg_filter_save_buf(struct ravg_filter_settings *); double ravg_filter_response(int, int, double); struct ravg_filter_settings * create_ravg_filter_copy(struct ravg_filter_settings *); #endif edfbrowser_153_source/PaxHeaders.2978/utc_date_time.c0000644000175000001440000000013212251654530021121 xustar000000000000000030 mtime=1386699096.471032554 30 atime=1386699096.471032554 30 ctime=1386699096.471032554 edfbrowser_153_source/utc_date_time.c0000644000175000001440000002033312251654530020653 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "utc_date_time.h" void date_time_to_utc(long long *seconds, struct date_time_struct date_time) { *seconds = (date_time.day - 1) * 86400LL; if(date_time.month>1) { *seconds += 2678400LL; } if(date_time.month>2) { if(date_time.year%4) { *seconds += 2419200LL; } else { *seconds += 2505600LL; } } if(date_time.month>3) { *seconds += 2678400LL; } if(date_time.month>4) { *seconds += 2592000LL; } if(date_time.month>5) { *seconds += 2678400LL; } if(date_time.month>6) { *seconds += 2592000LL; } if(date_time.month>7) { *seconds += 2678400LL; } if(date_time.month>8) { *seconds += 2678400LL; } if(date_time.month>9) { *seconds += 2592000LL; } if(date_time.month>10) { *seconds += 2678400LL; } if(date_time.month>11) { *seconds += 2592000LL; } *seconds += (date_time.year - 1970) * 31536000LL; *seconds += ((date_time.year - 1970 + 1) / 4) * 86400LL; *seconds += date_time.hour * 3600; *seconds += date_time.minute * 60; *seconds += date_time.second; switch(date_time.month) { case 1 : strcpy(date_time.month_str, "JAN"); break; case 2 : strcpy(date_time.month_str, "FEB"); break; case 3 : strcpy(date_time.month_str, "MAR"); break; case 4 : strcpy(date_time.month_str, "APR"); break; case 5 : strcpy(date_time.month_str, "MAY"); break; case 6 : strcpy(date_time.month_str, "JUN"); break; case 7 : strcpy(date_time.month_str, "JUL"); break; case 8 : strcpy(date_time.month_str, "AUG"); break; case 9 : strcpy(date_time.month_str, "SEP"); break; case 10 : strcpy(date_time.month_str, "OCT"); break; case 11 : strcpy(date_time.month_str, "NOV"); break; case 12 : strcpy(date_time.month_str, "DEC"); break; default : strcpy(date_time.month_str, "ERR"); break; } } void utc_to_date_time(long long seconds, struct date_time_struct *date_time) { date_time->year = 1970; while(1) { if(date_time->year%4) { if(seconds>=31536000) { date_time->year++; seconds -= 31536000; } else { break; } } else { if(seconds>=31622400) { date_time->year++; seconds -= 31622400; } else { break; } } } date_time->month = 1; if(seconds>=2678400) { date_time->month++; seconds -= 2678400; if(date_time->year%4) { if(seconds>=2419200) { date_time->month++; seconds -= 2419200; if(seconds>=2678400) { date_time->month++; seconds -= 2678400; if(seconds>=2592000) { date_time->month++; seconds -= 2592000; if(seconds>=2678400) { date_time->month++; seconds -= 2678400; if(seconds>=2592000) { date_time->month++; seconds -= 2592000; if(seconds>=2678400) { date_time->month++; seconds -= 2678400; if(seconds>=2678400) { date_time->month++; seconds -= 2678400; if(seconds>=2592000) { date_time->month++; seconds -= 2592000; if(seconds>=2678400) { date_time->month++; seconds -= 2678400; if(seconds>=2592000) { date_time->month++; seconds -= 2592000; if(seconds>=2678400) { date_time->month++; seconds -= 2678400; } } } } } } } } } } } } else { if(seconds>=2505600) { date_time->month++; seconds -= 2505600; if(seconds>=2678400) { date_time->month++; seconds -= 2678400; if(seconds>=2592000) { date_time->month++; seconds -= 2592000; if(seconds>=2678400) { date_time->month++; seconds -= 2678400; if(seconds>=2592000) { date_time->month++; seconds -= 2592000; if(seconds>=2678400) { date_time->month++; seconds -= 2678400; if(seconds>=2678400) { date_time->month++; seconds -= 2678400; if(seconds>=2592000) { date_time->month++; seconds -= 2592000; if(seconds>=2678400) { date_time->month++; seconds -= 2678400; if(seconds>=2592000) { date_time->month++; seconds -= 2592000; if(seconds>=2678400) { date_time->month++; seconds -= 2678400; } } } } } } } } } } } } } date_time->day = (seconds / 86400) + 1; seconds %= 86400; date_time->hour = seconds / 3600; seconds %= 3600; date_time->minute = seconds / 60; seconds %= 60; date_time->second = seconds; switch(date_time->month) { case 1 : strcpy(date_time->month_str, "JAN"); break; case 2 : strcpy(date_time->month_str, "FEB"); break; case 3 : strcpy(date_time->month_str, "MAR"); break; case 4 : strcpy(date_time->month_str, "APR"); break; case 5 : strcpy(date_time->month_str, "MAY"); break; case 6 : strcpy(date_time->month_str, "JUN"); break; case 7 : strcpy(date_time->month_str, "JUL"); break; case 8 : strcpy(date_time->month_str, "AUG"); break; case 9 : strcpy(date_time->month_str, "SEP"); break; case 10 : strcpy(date_time->month_str, "OCT"); break; case 11 : strcpy(date_time->month_str, "NOV"); break; case 12 : strcpy(date_time->month_str, "DEC"); break; default : strcpy(date_time->month_str, "ERR"); break; } } edfbrowser_153_source/PaxHeaders.2978/biosemi2bdfplus.h0000644000175000001440000000013212251654530021411 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/biosemi2bdfplus.h0000644000175000001440000000447712251654530021156 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef UI_BIOSEMI2BDFFORM_H #define UI_BIOSEMI2BDFFORM_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "mainwindow.h" #include "edflib.h" #include "popup_messagewindow.h" #include "edf_annot_list.h" class UI_Mainwindow; class UI_BIOSEMI2BDFPLUSwindow : public QObject { Q_OBJECT public: UI_BIOSEMI2BDFPLUSwindow(QWidget *parent); UI_Mainwindow *mainwindow; private: QLabel *label1[16], *label2, *label3, *label4; QLineEdit *lineEdit1[16]; QRadioButton *radioButton1, *radioButton2; QCheckBox *checkBox1; QPushButton *selectButton, *closeButton; QDialog *myobjectDialog; char inputpath[MAX_PATH_LENGTH], outputpath[MAX_PATH_LENGTH], *recent_opendir, *recent_savedir; private slots: void SelectFileButton(); }; #endif edfbrowser_153_source/PaxHeaders.2978/spectrumanalyzer.cpp0000644000175000001440000000013212251654530022263 xustar000000000000000030 mtime=1386699096.479032511 30 atime=1386699096.479032511 30 ctime=1386699096.479032511 edfbrowser_153_source/spectrumanalyzer.cpp0000644000175000001440000005435312251654530022026 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "spectrumanalyzer.h" UI_FreqSpectrumWindow::UI_FreqSpectrumWindow(struct signalcompblock *signal_comp, char *view_buf, UI_FreqSpectrumWindow **spectrdialog, int number, QWidget *w_parent) { int i; char str[1024]; long long l_temp; buf1 = NULL; buf2 = NULL; buf3 = NULL; busy = 0; spectrumdialog_is_destroyed = 0; flywheel_value = 1050; spectrumdialog = spectrdialog; spectrumdialognumber = number; mainwindow = (UI_Mainwindow *)w_parent; viewbuf = view_buf; signalcomp = signal_comp; for(i=strlen(signalcomp->edfhdr->filename); i>0; i--) { if((signalcomp->edfhdr->filename[i-1]=='/')||(signalcomp->edfhdr->filename[i-1]=='\\')) break; } if((signalcomp->edfhdr->viewtime + signalcomp->edfhdr->starttime_offset)>=0LL) { if(signalcomp->alias[0] != 0) { snprintf(signallabel, 512, " %s %i:%02i:%02i.%04i %s", signalcomp->alias, (int)((signalcomp->edfhdr->viewtime / TIME_DIMENSION)/ 3600LL), (int)(((signalcomp->edfhdr->viewtime / TIME_DIMENSION) % 3600LL) / 60LL), (int)((signalcomp->edfhdr->viewtime / TIME_DIMENSION) % 60LL), (int)((signalcomp->edfhdr->viewtime % TIME_DIMENSION) / 1000LL), signalcomp->edfhdr->filename + i); } else { snprintf(signallabel, 512, " %s %i:%02i:%02i.%04i %s", signalcomp->signallabel, (int)((signalcomp->edfhdr->viewtime / TIME_DIMENSION)/ 3600LL), (int)(((signalcomp->edfhdr->viewtime / TIME_DIMENSION) % 3600LL) / 60LL), (int)((signalcomp->edfhdr->viewtime / TIME_DIMENSION) % 60LL), (int)((signalcomp->edfhdr->viewtime % TIME_DIMENSION) / 1000LL), signalcomp->edfhdr->filename + i); } } else { l_temp = signalcomp->edfhdr->l_starttime + ((signalcomp->edfhdr->viewtime + signalcomp->edfhdr->starttime_offset) % (86400LL * TIME_DIMENSION)); if(l_temp<=0) { l_temp = (86400LL * TIME_DIMENSION) + l_temp; } l_temp = -signalcomp->edfhdr->viewtime; if(signalcomp->alias[0] != 0) { snprintf(signallabel, 512, " %s -%i:%02i:%02i.%04i %s", signalcomp->alias, (int)((l_temp / TIME_DIMENSION)/ 3600LL), (int)(((l_temp / TIME_DIMENSION) % 3600LL) / 60LL), (int)((l_temp / TIME_DIMENSION) % 60LL), (int)((l_temp % TIME_DIMENSION) / 1000LL), signalcomp->edfhdr->filename + i); } else { snprintf(signallabel, 512, " %s -%i:%02i:%02i.%04i %s", signalcomp->signallabel, (int)((l_temp / TIME_DIMENSION)/ 3600LL), (int)(((l_temp / TIME_DIMENSION) % 3600LL) / 60LL), (int)((l_temp / TIME_DIMENSION) % 60LL), (int)((l_temp % TIME_DIMENSION) / 1000LL), signalcomp->edfhdr->filename + i); } } remove_trailing_zeros(signallabel); strcpy(physdimension, signalcomp->physdimension); SpectrumDialog = new QDialog(); SpectrumDialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); SpectrumDialog->setMinimumSize(QSize(650, 480)); SpectrumDialog->setSizeGripEnabled(TRUE); SpectrumDialog->setModal(FALSE); SpectrumDialog->setWindowFlags(Qt::Window | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint); if(mainwindow->spectrum_sqrt) { snprintf(str, 512, "Amplitude Spectrum %s", signallabel); } else { snprintf(str, 512, "Power Spectral Density %s", signallabel); } SpectrumDialog->setWindowTitle(str); SpectrumDialog->setWindowIcon(QIcon(":/images/edf.png")); curve1 = new SignalCurve; curve1->setSignalColor(Qt::green); curve1->setBackgroundColor(Qt::black); curve1->setRasterColor(Qt::gray); curve1->setTraceWidth(0); curve1->setH_label("Hz"); curve1->setLowerLabel("Frequency"); if(mainwindow->spectrum_sqrt) { curve1->setV_label(physdimension); } else { snprintf(str, 512, "(%s)^2/Hz", physdimension); curve1->setV_label(str); } curve1->create_button("to Text"); curve1->setDashBoardEnabled(FALSE); flywheel1 = new UI_Flywheel; flywheel1->setMinimumSize(20, 85); amplitudeSlider = new QSlider; amplitudeSlider->setOrientation(Qt::Vertical); amplitudeSlider->setMinimum(1); amplitudeSlider->setMaximum(2000); amplitudeSlider->setValue(1000); amplitudeSlider->setInvertedAppearance(TRUE); amplitudeSlider->setMinimumSize(15, 280); amplitudeLabel = new QLabel; amplitudeLabel->setText("Amplitude"); amplitudeLabel->setMinimumSize(100, 15); amplitudeLabel->setAlignment(Qt::AlignHCenter); sqrtCheckBox = new QCheckBox("Amplitude"); sqrtCheckBox->setMinimumSize(70, 25); sqrtCheckBox->setTristate(FALSE); if(mainwindow->spectrum_sqrt) { sqrtCheckBox->setCheckState(Qt::Checked); } else { sqrtCheckBox->setCheckState(Qt::Unchecked); } BWCheckBox = new QCheckBox("B/W"); BWCheckBox->setMinimumSize(70, 25); BWCheckBox->setTristate(FALSE); if(mainwindow->spectrum_bw == 1) { BWCheckBox->setCheckState(Qt::Checked); } else { BWCheckBox->setCheckState(Qt::Unchecked); } vlayout3 = new QVBoxLayout; vlayout3->addStretch(100); vlayout3->addWidget(flywheel1, 100); vlayout3->addStretch(100); hlayout4 = new QHBoxLayout; hlayout4->addStretch(100); hlayout4->addLayout(vlayout3, 100); hlayout4->addStretch(100); hlayout4->addWidget(amplitudeSlider, 300); vlayout2 = new QVBoxLayout; vlayout2->setSpacing(20); vlayout2->addStretch(100); vlayout2->addWidget(amplitudeLabel, 0, Qt::AlignHCenter); vlayout2->addLayout(hlayout4, 200); vlayout2->addWidget(sqrtCheckBox); vlayout2->addWidget(BWCheckBox); spanSlider = new QSlider; spanSlider->setOrientation(Qt::Horizontal); spanSlider->setMinimum(10); spanSlider->setMaximum(1000); spanSlider->setValue(1000); spanSlider->setMinimumSize(500, 15); spanLabel = new QLabel; spanLabel->setText("Span"); spanLabel->setMinimumSize(110, 15); spanLabel->setAlignment(Qt::AlignHCenter); centerSlider = new QSlider; centerSlider->setOrientation(Qt::Horizontal); centerSlider->setMinimum(0); centerSlider->setMaximum(1000); centerSlider->setValue(0); centerSlider->setMinimumSize(500, 15); centerLabel = new QLabel; centerLabel->setText("Center"); centerLabel->setMinimumSize(110, 15); centerLabel->setAlignment(Qt::AlignHCenter); hlayout1 = new QHBoxLayout; hlayout1->setSpacing(20); hlayout1->addLayout(vlayout2); hlayout1->addWidget(curve1, 100); hlayout2 = new QHBoxLayout; hlayout2->setSpacing(20); hlayout2->addWidget(spanLabel); hlayout2->addWidget(spanSlider); hlayout2->addStretch(100); hlayout3 = new QHBoxLayout; hlayout3->setSpacing(20); hlayout3->addWidget(centerLabel); hlayout3->addWidget(centerSlider); hlayout3->addStretch(100); vlayout1 = new QVBoxLayout; vlayout1->setSpacing(20); vlayout1->addLayout(hlayout1); vlayout1->addLayout(hlayout2); vlayout1->addLayout(hlayout3); SpectrumDialog->setLayout(vlayout1); t1 = new QTimer(this); t1->setSingleShot(TRUE); t1->start(100); QObject::connect(t1, SIGNAL(timeout()), this, SLOT(update_curve())); QObject::connect(amplitudeSlider, SIGNAL(valueChanged(int)), this, SLOT(sliderMoved(int))); QObject::connect(spanSlider, SIGNAL(valueChanged(int)), this, SLOT(sliderMoved(int))); QObject::connect(centerSlider, SIGNAL(valueChanged(int)), this, SLOT(sliderMoved(int))); QObject::connect(sqrtCheckBox, SIGNAL(stateChanged(int)), this, SLOT(sliderMoved(int))); QObject::connect(BWCheckBox, SIGNAL(stateChanged(int)), this, SLOT(sliderMoved(int))); QObject::connect(SpectrumDialog, SIGNAL(destroyed(QObject *)), this, SLOT(SpectrumDialogDestroyed(QObject *))); QObject::connect(curve1, SIGNAL(extra_button_clicked()), this, SLOT(print_to_txt())); QObject::connect(flywheel1, SIGNAL(dialMoved(int)), this, SLOT(update_flywheel(int))); SpectrumDialog->show(); } void UI_FreqSpectrumWindow::update_flywheel(int new_value) { flywheel_value += new_value; if(flywheel_value < 10) { flywheel_value = 10; } if(flywheel_value > 100000) { flywheel_value = 100000; } sliderMoved(0); } void UI_FreqSpectrumWindow::print_to_txt() { int i; char str[1024], path[MAX_PATH_LENGTH]; FILE *outputfile; path[0] = 0; if(mainwindow->recent_savedir[0]!=0) { strcpy(path, mainwindow->recent_savedir); strcat(path, "/"); } strcat(path, "spectrum.txt"); strcpy(path, QFileDialog::getSaveFileName(0, "Export to text (ASCII)", QString::fromLocal8Bit(path), "Text files (*.txt *.TXT)").toLocal8Bit().data()); if(!strcmp(path, "")) { return; } get_directory_from_path(mainwindow->recent_savedir, path, MAX_PATH_LENGTH); outputfile = fopen(path, "wb"); if(outputfile == NULL) { snprintf(str, 1024, "Can not open file %s for writing.", path); QMessageBox messagewindow(QMessageBox::Critical, "Error", QString::fromLocal8Bit(str)); messagewindow.exec(); return; } sprintf(str, "FFT Power Spectral Density (Power/%fHz)\n", freqstep); remove_trailing_zeros(str); fprintf(outputfile, "%s", str); if(signalcomp->alias[0] != 0) { fprintf(outputfile, "Signal: %s\n", signalcomp->alias); } else { fprintf(outputfile, "Signal: %s\n", signalcomp->signallabel); } sprintf(str, "FFT blocksize: %i\n", mainwindow->maxdftblocksize); sprintf(str + strlen(str), "FFT resolution: %f Hz\n", freqstep); sprintf(str + strlen(str), "Data Samples: %i\n", samples); sprintf(str + strlen(str), "Power Samples: %i\n", steps); sprintf(str + strlen(str), "Samplefrequency: %f Hz\n", (double)signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].smp_per_record / ((double)signalcomp->edfhdr->long_data_record_duration / TIME_DIMENSION)); remove_trailing_zeros(str); fprintf(outputfile, "%s", str); for(i=0; icheckState() == Qt::Checked) { mainwindow->spectrum_sqrt = 1; sprintf(str, "Amplitude Spectrum %s", signallabel); SpectrumDialog->setWindowTitle(str); curve1->setV_label(physdimension); } else { mainwindow->spectrum_sqrt = 0; sprintf(str, "Power Spectral Density %s", signallabel); SpectrumDialog->setWindowTitle(str); sprintf(str, "(%s)^2/Hz", physdimension); curve1->setV_label(str); } if(BWCheckBox->isChecked() == TRUE) { curve1->setSignalColor(Qt::black); curve1->setBackgroundColor(Qt::white); curve1->setRasterColor(Qt::black); curve1->setMarker1Color(Qt::black); curve1->setBorderColor(Qt::white); curve1->setTextColor(Qt::black); curve1->setCrosshairColor(Qt::black); mainwindow->spectrum_bw = 1; } else { curve1->setSignalColor(Qt::green); curve1->setBackgroundColor(Qt::black); curve1->setRasterColor(Qt::gray); curve1->setMarker1Color(Qt::yellow); curve1->setBorderColor(Qt::lightGray); curve1->setTextColor(Qt::black); curve1->setCrosshairColor(Qt::red); mainwindow->spectrum_bw = 0; } spanstep = spanSlider->value() * steps / 1000; startstep = centerSlider->value() * (steps - spanstep) / 1000; stopstep = startstep + spanstep; if(mainwindow->spectrum_sqrt) { curve1->drawCurve(buf3 + startstep, stopstep - startstep, (maxvalue_sqrt * ((double)flywheel_value / 1000.0) * (double)amplitudeSlider->value()) / 1000.0, 0.0); } else { curve1->drawCurve(buf2 + startstep, stopstep - startstep, (maxvalue * ((double)flywheel_value / 1000.0) * (double)amplitudeSlider->value()) / 1000.0, 0.0); } max_freq = ((double)samplefreq / 2.0) * stopstep / steps; precision = 0; if(max_freq < 10.0) { precision = 1; } if(max_freq < 1.0) { precision = 2; } if(max_freq < 0.1) { precision = 3; } if(max_freq < 0.01) { precision = 4; } start_freq = ((double)samplefreq / 2.0) * startstep / steps; curve1->setH_RulerValues(start_freq, max_freq); centerLabel->setText(QString::number(start_freq + ((max_freq - start_freq) / 2.0), 'f', precision).append(" Hz").prepend("Center ")); spanLabel->setText(QString::number(max_freq - start_freq, 'f', precision).append(" Hz").prepend("Span ")); } void UI_FreqSpectrumWindow::update_curve() { int i, j, k, dftblocksize, dftblocks, samplesleft, fft_outputbufsize; long long s, s2; char str[512]; double dig_value=0.0, f_tmp=0.0; union { unsigned int one; signed int one_signed; unsigned short two[2]; signed short two_signed[2]; unsigned char four[4]; } var; if(signalcomp == NULL) { return; } if(busy) { return; } viewbuf = mainwindow->viewbuf; if(viewbuf == NULL) { return; } busy = 1; curve1->setUpdatesEnabled(FALSE); samples = signalcomp->samples_on_screen; if(signalcomp->samples_on_screen > signalcomp->sample_stop) { samples = signalcomp->sample_stop; } samples -= signalcomp->sample_start; if((samples < 10) || (viewbuf == NULL)) { curve1->setUpdatesEnabled(TRUE); busy = 0; curve1->clear(); return; } if(buf1 != NULL) { free(buf1); } buf1 = (double *)malloc(sizeof(double) * signalcomp->samples_on_screen); if(buf1 == NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "The system was not able to provide enough resources (memory) to perform the requested action.\n" "Decrease the timescale and try again."); messagewindow.exec(); return; } samples = 0; for(s=signalcomp->sample_start; ssamples_on_screen; s++) { if(s>signalcomp->sample_stop) break; dig_value = 0.0; s2 = s + signalcomp->sample_timeoffset - signalcomp->sample_start; for(j=0; jnum_of_signals; j++) { if(signalcomp->edfhdr->bdf) { var.two[0] = *((unsigned short *)( viewbuf + signalcomp->viewbufoffset + (signalcomp->edfhdr->recordsize * (s2 / signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].smp_per_record)) + signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].buf_offset + ((s2 % signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].smp_per_record) * 3))); var.four[2] = *((unsigned char *)( viewbuf + signalcomp->viewbufoffset + (signalcomp->edfhdr->recordsize * (s2 / signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].smp_per_record)) + signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].buf_offset + ((s2 % signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].smp_per_record) * 3) + 2)); if(var.four[2]&0x80) { var.four[3] = 0xff; } else { var.four[3] = 0x00; } f_tmp = var.one_signed; } if(signalcomp->edfhdr->edf) { f_tmp = *(((short *)( viewbuf + signalcomp->viewbufoffset + (signalcomp->edfhdr->recordsize * (s2 / signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].smp_per_record)) + signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].buf_offset)) + (s2 % signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].smp_per_record)); } f_tmp += signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].offset; f_tmp *= signalcomp->factor[j]; dig_value += f_tmp; } for(k=0; kfilter_cnt; k++) { dig_value = first_order_filter(dig_value, signalcomp->filter[k]); } for(k=0; kravg_filter_cnt; k++) { if(s==signalcomp->sample_start) { ravg_filter_restore_buf(signalcomp->ravg_filter[k]); } dig_value = run_ravg_filter(dig_value, signalcomp->ravg_filter[k]); } for(k=0; kfidfilter_cnt; k++) { if(s==signalcomp->sample_start) { memcpy(signalcomp->fidbuf[k], signalcomp->fidbuf2[k], fid_run_bufsize(signalcomp->fid_run[k])); } dig_value = signalcomp->fidfuncp[k](signalcomp->fidbuf[k], dig_value); } if(signalcomp->ecg_filter != NULL) { if(s==signalcomp->sample_start) { ecg_filter_restore_buf(signalcomp->ecg_filter); } dig_value = run_ecg_filter(dig_value, signalcomp->ecg_filter); } if(s>=signalcomp->sample_start) { buf1[samples++] = dig_value * signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].bitvalue; } } samplefreq = (double)signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].smp_per_record / ((double)signalcomp->edfhdr->long_data_record_duration / TIME_DIMENSION); dftblocksize = mainwindow->maxdftblocksize; if(dftblocksize & 1) { dftblocksize--; } dftblocks = 1; if(dftblocksize < samples) { dftblocks = samples / dftblocksize; } else { dftblocksize = samples; } if(dftblocksize & 1) { dftblocksize--; } samplesleft = samples % dftblocksize; if(samplesleft & 1) { samplesleft--; } freqstep = samplefreq / (double)dftblocksize; fft_outputbufsize = dftblocksize / 2; steps = fft_outputbufsize; if(buf2 != NULL) { free(buf2); } buf2 = (double *)calloc(1, sizeof(double) * fft_outputbufsize); if(buf2 == NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "The system was not able to provide enough resources (memory) to perform the requested action."); messagewindow.exec(); free(buf1); buf1 = NULL; return; } if(buf3 != NULL) { free(buf3); } buf3 = (double *)malloc(sizeof(double) * fft_outputbufsize); if(buf3 == NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "The system was not able to provide enough resources (memory) to perform the requested action."); messagewindow.exec(); free(buf1); free(buf2); buf1 = NULL; buf2 = NULL; return; } maxvalue = 0.000001; maxvalue_sqrt = 0.000001; #ifdef CHECK_POWERSPECTRUM printf("samples is %i dftblocksize is %i dftblocks is %i samplesleft is %i fft_outputbufsize is %i steps is %i\n", samples, dftblocksize, dftblocks, samplesleft, fft_outputbufsize, steps); double power1=0.0, power2=0.0; for(i=0; iecg_filter == NULL) { buf2[0] /= 2.0; // DC! } else { buf2[0] = 0.0; // Remove DC because heart rate is always a positive value } free(cfg); free(kiss_fftbuf); for(i=0; i maxvalue) { maxvalue = buf2[i]; } if(buf3[i] > maxvalue_sqrt) { maxvalue_sqrt = buf3[i]; } } } if(samplesleft) { dftblocks++; } #ifdef CHECK_POWERSPECTRUM power1 /= samples; power2 *= freqstep; printf("\n power1 is %f\n power2 is %f\n\n", power1, power2); #endif if(buf1 != NULL) { free(buf1); buf1 = NULL; } sprintf(str, "FFT resolution: %f Hz %i blocks of %i samples", freqstep, dftblocks, dftblocksize); remove_trailing_zeros(str); curve1->setUpperLabel1(str); curve1->setUpperLabel2(signallabel); sliderMoved(0); curve1->setUpdatesEnabled(TRUE); busy = 0; } void UI_FreqSpectrumWindow::SpectrumDialogDestroyed(QObject *) { spectrumdialog_is_destroyed = 1; spectrumdialog[spectrumdialognumber] = NULL; delete this; } UI_FreqSpectrumWindow::~UI_FreqSpectrumWindow() { if(!spectrumdialog_is_destroyed) { SpectrumDialog->close(); } if(buf2 != NULL) { free(buf2); } if(buf3 != NULL) { free(buf3); } spectrumdialog[spectrumdialognumber] = NULL; } edfbrowser_153_source/PaxHeaders.2978/check_for_updates.cpp0000644000175000001440000000013212251654530022323 xustar000000000000000030 mtime=1386699096.477032522 30 atime=1386699096.477032522 30 ctime=1386699096.477032522 edfbrowser_153_source/check_for_updates.cpp0000644000175000001440000000647112251654530022064 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "check_for_updates.h" Check_for_updates::Check_for_updates() { QNetworkRequest request; QNetworkReply *reply; manager = new QNetworkAccessManager(this); request.setUrl(QUrl("http://www.teuniz.net/edfbrowser/latest_version.txt")); request.setRawHeader("User-Agent", PROGRAM_NAME " " PROGRAM_VERSION " OS_UNKNOWN"); #ifdef Q_WS_X11 request.setRawHeader("User-Agent", PROGRAM_NAME " " PROGRAM_VERSION " Q_WS_X11"); #endif #ifdef Q_WS_MAC request.setRawHeader("User-Agent", PROGRAM_NAME " " PROGRAM_VERSION " Q_WS_MAC"); #endif #ifdef Q_WS_WIN request.setRawHeader("User-Agent", PROGRAM_NAME " " PROGRAM_VERSION " Q_WS_WIN"); #endif request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysNetwork); reply = manager->get(request); connect(reply, SIGNAL(finished()), this, SLOT(replyFinished())); } void Check_for_updates::replyFinished() { long long int n; char buf[128]; int this_version, latest_version; QNetworkReply *reply = qobject_cast(sender()); if(reply->error() != QNetworkReply::NoError) { reply->deleteLater(); return; } if(reply->bytesAvailable() < 31) { reply->deleteLater(); return; } n = reply->read(buf, 100); if(n < 31) { reply->deleteLater(); return; } reply->deleteLater(); buf[30] = 0; if(strncmp(buf, "EDFbrowser latest version: ", 27)) { return; } if(is_integer_number(buf + 27)) { return; } latest_version = atoi(buf + 27); if((latest_version < 1) || (latest_version > 1000000)) { return; } sprintf(buf, PROGRAM_VERSION); buf[1] = buf[0]; this_version = atoi(buf + 1); if(this_version >= latest_version) { return; } QMessageBox messagewindow(QMessageBox::Information, "New version available", "A newer version of EDFbrowser is available.\n" "Do you want to download the new version now?", QMessageBox::Yes | QMessageBox::No); if(messagewindow.exec() != QMessageBox::Yes) { return; } QDesktopServices::openUrl(QUrl("http://www.teuniz.net/edfbrowser/")); } edfbrowser_153_source/PaxHeaders.2978/ravg_filter.cpp0000644000175000001440000000013212251654530021157 xustar000000000000000030 mtime=1386699096.478032517 30 atime=1386699096.478032517 30 ctime=1386699096.478032517 edfbrowser_153_source/ravg_filter.cpp0000644000175000001440000001173512251654530020717 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * The current version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "ravg_filter.h" struct ravg_filter_settings * create_ravg_filter(int type, int size) { struct ravg_filter_settings *settings; if((size < 2) || (size > 10000)) return(NULL); if((type < 0) || (type > 1)) return(NULL); settings = (struct ravg_filter_settings *) calloc(1, sizeof(struct ravg_filter_settings)); if(settings==NULL) return(NULL); settings->size = size; settings->type = type; settings->first_sample = 1; settings->buf_pntr = 0; settings->buf_pntr2 = 0; settings->mean = 0.0; settings->mean2 = 0.0; settings->buf = (double *)calloc(1, sizeof(double) * size); if(settings->buf == NULL) { free(settings); return(NULL); } settings->buf2 = (double *)calloc(1, sizeof(double) * size); if(settings->buf2 == NULL) { free(settings->buf); free(settings); return(NULL); } return(settings); } struct ravg_filter_settings * create_ravg_filter_copy(struct ravg_filter_settings *src) { struct ravg_filter_settings *settings; settings = (struct ravg_filter_settings *) calloc(1, sizeof(struct ravg_filter_settings)); if(settings==NULL) { return(NULL); } memcpy(settings, src, sizeof(struct ravg_filter_settings)); settings->buf = (double *)calloc(1, sizeof(double) * settings->size); if(settings->buf == NULL) { free(settings); return(NULL); } memcpy(settings->buf, src->buf, settings->size); settings->buf2 = (double *)calloc(1, sizeof(double) * settings->size); if(settings->buf2 == NULL) { free(settings->buf); free(settings); return(NULL); } memcpy(settings->buf2, src->buf2, settings->size); return(settings); } void reset_ravg_filter(double offset, struct ravg_filter_settings *settings) { int i; for(i=0; isize; i++) { settings->buf[i] = offset; } memcpy(settings->buf2, settings->buf, settings->size * sizeof(double)); settings->mean = offset; settings->mean2 = offset; settings->buf_pntr = 0; settings->buf_pntr2 = 0; } void ravg_filter_restore_buf(struct ravg_filter_settings *settings) { memcpy(settings->buf, settings->buf2, settings->size * sizeof(double)); settings->mean = settings->mean2; settings->buf_pntr = settings->buf_pntr2; } void ravg_filter_save_buf(struct ravg_filter_settings *settings) { memcpy(settings->buf2, settings->buf, settings->size * sizeof(double)); settings->mean2 = settings->mean; settings->buf_pntr2 = settings->buf_pntr; } double run_ravg_filter(double new_input, struct ravg_filter_settings *settings) { int i; if(settings->first_sample) { settings->first_sample = 0; for(i=0; isize; i++) { settings->buf[i] = new_input; } settings->mean = new_input; return(new_input); } settings->mean -= (settings->buf[settings->buf_pntr] / settings->size); settings->buf[settings->buf_pntr] = new_input; settings->buf_pntr++; if(settings->buf_pntr >= settings->size) { settings->buf_pntr = 0; } settings->mean += (new_input / settings->size); if(settings->type == 0) /* highpass */ { return(settings->buf[(settings->buf_pntr + (settings->size / 2)) % settings->size] - settings->mean); } if(settings->type == 1) /* lowpass */ { return(settings->mean); } return(0.0); } void free_ravg_filter(struct ravg_filter_settings *settings) { free(settings->buf); free(settings->buf2); free(settings); } double ravg_filter_response(int type, int size, double freq) { if((type < 0) || (type > 1) || (size < 2) || (freq > 0.5)) { return(1.0); } if(type) { if(freq < 0.000001) { return(1.0); } return(fabs((sin(M_PI * freq * (double)size)) / ((double)size * sin(M_PI * freq)))); } if(freq < 0.000001) { return(0.0); } return(1.0 - fabs((sin(M_PI * freq * (double)size)) / ((double)size * sin(M_PI * freq)))); } edfbrowser_153_source/PaxHeaders.2978/edit_predefined_mtg.cpp0000644000175000001440000000013212251654530022634 xustar000000000000000030 mtime=1386699096.477032522 30 atime=1386699096.477032522 30 ctime=1386699096.477032522 edfbrowser_153_source/edit_predefined_mtg.cpp0000644000175000001440000001101612251654530022364 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "edit_predefined_mtg.h" UI_edit_predefined_mtg_window::UI_edit_predefined_mtg_window(QWidget *w_parent) { int i; char str[1200]; mainwindow = (UI_Mainwindow *)w_parent; edit_predefined_mtg_Dialog = new QDialog; edit_predefined_mtg_Dialog->setMinimumSize(800, 265); edit_predefined_mtg_Dialog->setMaximumSize(800, 265); edit_predefined_mtg_Dialog->setWindowTitle("Edit key-bindings for montages"); edit_predefined_mtg_Dialog->setModal(TRUE); edit_predefined_mtg_Dialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); mtg_path_list = new QListWidget(edit_predefined_mtg_Dialog); mtg_path_list->setGeometry(10, 10, 780, 210); mtg_path_list->setSelectionBehavior(QAbstractItemView::SelectRows); mtg_path_list->setSelectionMode(QAbstractItemView::SingleSelection); mtg_path_list->setSpacing(1); for(i=0; i < MAXPREDEFINEDMONTAGES; i++) { sprintf(str, "F%i : ", i + 1); if(mainwindow->predefined_mtg_path[i][0] != 0) { strcat(str, &(mainwindow->predefined_mtg_path[i][0])); } new QListWidgetItem(str, mtg_path_list); } CloseButton = new QPushButton(edit_predefined_mtg_Dialog); CloseButton->setGeometry(QRect(690, 230, 100, 25)); CloseButton->setText("Close"); QObject::connect(CloseButton, SIGNAL(clicked()), edit_predefined_mtg_Dialog, SLOT(close())); QObject::connect(mtg_path_list, SIGNAL(itemClicked(QListWidgetItem *)), this, SLOT(rowClicked(QListWidgetItem *))); edit_predefined_mtg_Dialog->exec(); } void UI_edit_predefined_mtg_window::rowClicked(QListWidgetItem *item) { row = mtg_path_list->row(item); listItem = item; dialog = new QDialog(edit_predefined_mtg_Dialog); dialog->setMinimumSize(QSize(140, 135)); dialog->setMaximumSize(QSize(140, 135)); dialog->setWindowTitle("Entry"); dialog->setModal(TRUE); dialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); button1 = new QPushButton(dialog); button1->setGeometry(20, 20, 100, 25); button1->setText("Change"); button2 = new QPushButton(dialog); button2->setGeometry(20, 55, 100, 25); button2->setText("Remove"); button3 = new QPushButton(dialog); button3->setGeometry(20, 90, 100, 25); button3->setText("Cancel"); QObject::connect(button1, SIGNAL(clicked()), this, SLOT(adEntry())); QObject::connect(button2, SIGNAL(clicked()), this, SLOT(removeEntry())); QObject::connect(button3, SIGNAL(clicked()), dialog, SLOT(close())); dialog->exec(); } void UI_edit_predefined_mtg_window::adEntry() { char str[1200], path[MAX_PATH_LENGTH]; dialog->close(); strcpy(path, QFileDialog::getOpenFileName(0, "Select montage", QString::fromLocal8Bit(mainwindow->recent_montagedir), "MTG files (*.mtg *.MTG)").toLocal8Bit().data()); if(!strcmp(path, "")) { return; } get_directory_from_path(mainwindow->recent_montagedir, path, MAX_PATH_LENGTH); strcpy(&(mainwindow->predefined_mtg_path[row][0]), path); mainwindow->load_predefined_mtg_act[row]->setText(QString::fromLocal8Bit(mainwindow->predefined_mtg_path[row])); sprintf(str, "F%i : ", row + 1); strcat(str, path); listItem->setText(str); } void UI_edit_predefined_mtg_window::removeEntry() { char str[32]; dialog->close(); mainwindow->predefined_mtg_path[row][0] = 0; mainwindow->load_predefined_mtg_act[row]->setText("Empty"); sprintf(str, "F%i :", row + 1); listItem->setText(str); } edfbrowser_153_source/PaxHeaders.2978/emsa2edf.cpp0000644000175000001440000000013212251654530020341 xustar000000000000000030 mtime=1386699096.477032522 30 atime=1386699096.477032522 30 ctime=1386699096.477032522 edfbrowser_153_source/emsa2edf.cpp0000644000175000001440000005655112251654530020106 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "emsa2edf.h" #if defined(__APPLE__) || defined(__MACH__) || defined(__APPLE_CC__) #define fopeno fopen #else #define fseeko fseeko64 #define ftello ftello64 #define fopeno fopen64 #endif UI_EMSA2EDFwindow::UI_EMSA2EDFwindow(char *recent_dir, char *save_dir) { char txt_string[2048]; recent_opendir = recent_dir; recent_savedir = save_dir; myobjectDialog = new QDialog; myobjectDialog->setMinimumSize(QSize(600, 480)); myobjectDialog->setMaximumSize(QSize(600, 480)); myobjectDialog->setWindowTitle("Emsa to EDF+ converter"); myobjectDialog->setModal(TRUE); myobjectDialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); pushButton1 = new QPushButton(myobjectDialog); pushButton1->setGeometry(QRect(20, 430, 100, 26)); pushButton1->setText("Select File"); pushButton2 = new QPushButton(myobjectDialog); pushButton2->setGeometry(QRect(480, 430, 100, 26)); pushButton2->setText("Close"); textEdit1 = new QTextEdit(myobjectDialog); textEdit1->setGeometry(QRect(20, 20, 560, 380)); textEdit1->setFrameStyle(QFrame::Panel | QFrame::Sunken); textEdit1->setReadOnly(TRUE); textEdit1->setLineWrapMode(QTextEdit::NoWrap); sprintf(txt_string, "Emsa to EDF+ converter.\n"); textEdit1->append(txt_string); QObject::connect(pushButton1, SIGNAL(clicked()), this, SLOT(SelectFileButton())); QObject::connect(pushButton2, SIGNAL(clicked()), myobjectDialog, SLOT(close())); myobjectDialog->exec(); } void UI_EMSA2EDFwindow::SelectFileButton() { FILE *inputfile=NULL, *outputfile=NULL, *logfile=NULL; int i, j, k, channels, record_size, samplefrequency, hdrsize, samples_in_record, bufsize, max_buf_records, raster, data_records, records_in_buf, error, len, seq_nr, year, b_year, b_date, seconds, deci_seconds, datrecduris1, gender, tallen=0, annot_cnt=0, patientcode=0, annots_written=0, time_on, time_off, duration_present=0; long long filesize; char path[MAX_PATH_LENGTH], scratchpad[256], *buf, date[9], time[9], month[4], patientname[128], b_month[4], *p, equipment[41], handedness[16], weight[16], birthdate[16], txt_string[2048], outputfilename[MAX_PATH_LENGTH]; union{ int number; char str[4]; } var; pushButton1->setEnabled(FALSE); strcpy(path, QFileDialog::getOpenFileName(0, "Select inputfile", QString::fromLocal8Bit(recent_opendir), "PLG files (*.plg *.PLG)").toLocal8Bit().data()); if(!strcmp(path, "")) { pushButton1->setEnabled(TRUE); return; } get_directory_from_path(recent_opendir, path, MAX_PATH_LENGTH); /***************** check header ******************************/ inputfile = fopeno(path, "rb"); if(inputfile==NULL) { snprintf(txt_string, 2048, "Can not open file %s for reading.\n", path); textEdit1->append(QString::fromLocal8Bit(txt_string)); pushButton1->setEnabled(TRUE); return; } fseeko(inputfile, 0LL, SEEK_END); filesize = ftello(inputfile); if(filesize<1538) { textEdit1->append("Error, filesize is too small.\n"); fclose(inputfile); pushButton1->setEnabled(TRUE); return; } rewind(inputfile); if(fread(scratchpad, 3, 1, inputfile)!=1) { textEdit1->append("Read error.\n"); fclose(inputfile); pushButton1->setEnabled(TRUE); return; } if((strncmp(scratchpad, "PBJ", 3))&&(strncmp(scratchpad, "BPC", 3))) { textEdit1->append("Error, file id does not match.\n"); fclose(inputfile); pushButton1->setEnabled(TRUE); return; } fseeko(inputfile, 3LL, SEEK_SET); channels = fgetc(inputfile); if(channels==EOF) { textEdit1->append("Read error.\n"); fclose(inputfile); pushButton1->setEnabled(TRUE); return; } if(!channels) { textEdit1->append("Error, number of channels is 0.\n"); fclose(inputfile); pushButton1->setEnabled(TRUE); return; } hdrsize = 1024 + (512 * channels); if(filesize<(hdrsize + (2 * channels))) { textEdit1->append("Error, filesize is too small.\n"); fclose(inputfile); pushButton1->setEnabled(TRUE); return; } fseeko(inputfile, 10LL, SEEK_SET); samplefrequency = 256 * fgetc(inputfile); fseeko(inputfile, 9LL, SEEK_SET); samplefrequency += fgetc(inputfile); if(!samplefrequency) { textEdit1->append("Error, samplefrequency is 0 Hz.\n"); fclose(inputfile); pushButton1->setEnabled(TRUE); return; } if(filesize<(hdrsize + (2 * channels * samplefrequency))) { textEdit1->append("Error, filesize is too small.\n"); fclose(inputfile); pushButton1->setEnabled(TRUE); return; } if(get_string(scratchpad, inputfile, 205, 32)!=8) { textEdit1->append("Error, can not read startdate.\n"); fclose(inputfile); pushButton1->setEnabled(TRUE); return; } error = 0; if((scratchpad[0]<'0')||(scratchpad[0]>'9')) error = 1; if((scratchpad[1]<'0')||(scratchpad[1]>'9')) error = 1; date[6] = scratchpad[2]; date[7] = scratchpad[3]; date[3] = scratchpad[4]; date[4] = scratchpad[5]; date[0] = scratchpad[6]; date[1] = scratchpad[7]; date[2] = 0; date[5] = 0; date[8] = 0; if((date[0]<'0')||(date[0]>'9')) error = 1; if((date[1]<'0')||(date[1]>'9')) error = 1; if((date[3]<'0')||(date[3]>'9')) error = 1; if((date[4]<'0')||(date[4]>'9')) error = 1; if((date[6]<'0')||(date[6]>'9')) error = 1; if((date[7]<'0')||(date[7]>'9')) error = 1; scratchpad[4] = 0; year = atoi(scratchpad); if(get_string(scratchpad, inputfile, 214, 32)!=8) { textEdit1->append("Error, can not read starttime.\n"); fclose(inputfile); pushButton1->setEnabled(TRUE); return; } strcpy(time, scratchpad); if(time[2] != ':') error = 1; if(time[5] != ':') error = 1; time[2] = 0; time[5] = 0; time[8] = 0; if((time[0]<'0')||(time[0]>'9')) error = 1; if((time[1]<'0')||(time[1]>'9')) error = 1; if((time[3]<'0')||(time[3]>'9')) error = 1; if((time[4]<'0')||(time[4]>'9')) error = 1; if((time[6]<'0')||(time[6]>'9')) error = 1; if((time[7]<'0')||(time[7]>'9')) error = 1; if((atoi(date)<1)||(atoi(date)>31)) error = 1; if((atoi(date+3)<1)||(atoi(date+3)>12)) error = 1; if(atoi(time)>23) error = 1; if(atoi(time+3)>59) error = 1; if(atoi(time+6)>59) error = 1; if(error) { textEdit1->append("Error, can not read startdate or starttime.\n"); fclose(inputfile); pushButton1->setEnabled(TRUE); return; } date[2] = '.'; date[5] = '.'; time[2] = '.'; time[5] = '.'; i = atoi(date+3); switch(i) { case 1 : strcpy(month, "JAN"); break; case 2 : strcpy(month, "FEB"); break; case 3 : strcpy(month, "MAR"); break; case 4 : strcpy(month, "APR"); break; case 5 : strcpy(month, "MAY"); break; case 6 : strcpy(month, "JUN"); break; case 7 : strcpy(month, "JUL"); break; case 8 : strcpy(month, "AUG"); break; case 9 : strcpy(month, "SEP"); break; case 10 : strcpy(month, "OCT"); break; case 11 : strcpy(month, "NOV"); break; case 12 : strcpy(month, "DEC"); break; default : strcpy(month, "ERR"); break; } if(get_string(scratchpad, inputfile, 169, 32)!=8) { strcpy(birthdate, "X"); } else { error = 0; for(i=0; i<8; i++) { if((scratchpad[i]<'0')||(scratchpad[i]>'9')) error = 1; } scratchpad[8] = 0; b_date = atoi(scratchpad+6); if((b_date<1)||(b_date>31)) error = 1; scratchpad[6] = 0; i = atoi(scratchpad+4); if((i<1)||(i>12)) error = 1; switch(i) { case 1 : strcpy(b_month, "JAN"); break; case 2 : strcpy(b_month, "FEB"); break; case 3 : strcpy(b_month, "MAR"); break; case 4 : strcpy(b_month, "APR"); break; case 5 : strcpy(b_month, "MAY"); break; case 6 : strcpy(b_month, "JUN"); break; case 7 : strcpy(b_month, "JUL"); break; case 8 : strcpy(b_month, "AUG"); break; case 9 : strcpy(b_month, "SEP"); break; case 10 : strcpy(b_month, "OCT"); break; case 11 : strcpy(b_month, "NOV"); break; case 12 : strcpy(b_month, "DEC"); break; default : strcpy(b_month, "ERR"); break; } scratchpad[4] = 0; b_year = atoi(scratchpad); if(error) { strcpy(birthdate, "X"); } else { sprintf(birthdate, "%02i-%s-%04i", b_date, b_month, b_year); } } len = get_string(patientname, inputfile, 11, 30); if(len) { latin1_to_ascii(patientname, len); for(i=0; iappend("Read error.\n"); fclose(inputfile); pushButton1->setEnabled(TRUE); return; } fseeko(inputfile, 8LL, SEEK_SET); seq_nr = fgetc(inputfile); if(seq_nr==EOF) { textEdit1->append("Read error.\n"); fclose(inputfile); pushButton1->setEnabled(TRUE); return; } fseeko(inputfile, 203LL, SEEK_SET); gender = fgetc(inputfile); if((gender!='M')&&(gender!='F')) { gender = 'X'; } len = fgetc(inputfile); switch(len) { case 'E' : strcpy(handedness, " lefthanded"); break; case 'D' : strcpy(handedness, " righthanded"); break; default : handedness[0] = 0; break; } len = get_string(weight + 1, inputfile, 351, 6); if(len) { latin1_to_ascii(weight + 1, len); weight[0] = ' '; strcat(weight, " Kg"); } else { weight[0] = 0; } len = get_string(equipment, inputfile, 309, 40); if(len) { latin1_to_ascii(equipment, len); for(i=0; iappend("Malloc error. (logbuf)\n"); fclose(inputfile); fclose(logfile); pushButton1->setEnabled(TRUE); return; } for(i=0; iappend("Error, can not read event starttime in .LBK file.\n"); fclose(inputfile); fclose(logfile); free(logbuf); return; } if(scratchpad[2] != ':') error = 1; if(scratchpad[5] != ':') error = 1; scratchpad[2] = 0; scratchpad[5] = 0; scratchpad[8] = 0; if((scratchpad[0]<'0')||(scratchpad[0]>'9')) error = 1; if((scratchpad[1]<'0')||(scratchpad[1]>'9')) error = 1; if((scratchpad[3]<'0')||(scratchpad[3]>'9')) error = 1; if((scratchpad[4]<'0')||(scratchpad[4]>'9')) error = 1; if((scratchpad[6]<'0')||(scratchpad[6]>'9')) error = 1; if((scratchpad[7]<'0')||(scratchpad[7]>'9')) error = 1; if(atoi(scratchpad)>23) error = 1; if(atoi(scratchpad+3)>59) error = 1; if(atoi(scratchpad+6)>59) error = 1; if(error) { textEdit1->append("Error, can not read event starttime in .LBK file.\n"); fclose(inputfile); fclose(logfile); free(logbuf); return; } time_on = atoi(scratchpad) * 3600; time_on += atoi(scratchpad+3) * 60; time_on += atoi(scratchpad+6); if(get_string(scratchpad, logfile, i * 69 + 9, 10)!=8) { textEdit1->append("Error, can not read event stoptime in .LBK file.\n"); fclose(inputfile); fclose(logfile); free(logbuf); return; } if(scratchpad[2] != ':') error = 1; if(scratchpad[5] != ':') error = 1; scratchpad[2] = 0; scratchpad[5] = 0; scratchpad[8] = 0; if((scratchpad[0]<'0')||(scratchpad[0]>'9')) error = 1; if((scratchpad[1]<'0')||(scratchpad[1]>'9')) error = 1; if((scratchpad[3]<'0')||(scratchpad[3]>'9')) error = 1; if((scratchpad[4]<'0')||(scratchpad[4]>'9')) error = 1; if((scratchpad[6]<'0')||(scratchpad[6]>'9')) error = 1; if((scratchpad[7]<'0')||(scratchpad[7]>'9')) error = 1; if(atoi(scratchpad)>23) error = 1; if(atoi(scratchpad+3)>59) error = 1; if(atoi(scratchpad+6)>59) error = 1; if(error) { textEdit1->append("Error, can not read event stoptime in .LBK file.\n"); fclose(inputfile); fclose(logfile); free(logbuf); return; } time_off = atoi(scratchpad) * 3600; time_off += atoi(scratchpad+3) * 60; time_off += atoi(scratchpad+6); logbuf[i].duration = time_off - time_on; if(logbuf[i].duration<0) { textEdit1->append("Error, event duration in .LBK file is < 0.\n"); fclose(inputfile); fclose(logfile); free(logbuf); return; } if(logbuf[i].duration) { duration_present = 1; } k = (atoi(time) * 3600); k += (atoi(time+3) * 60); k += atoi(time+6); logbuf[i].onset = time_on - k; if(logbuf[i].onset < 0) { logbuf[i].onset += 86400; } len = get_string(logbuf[i].description, logfile, i * 69 + 18, 40); if(len>2) { for(j=len-1; j>0; j--) { if(logbuf[i].description[j]==' ') { logbuf[i].description[j] = 0; len--; } else break; } } latin1_to_utf8(logbuf[i].description, 80); len = strlen(logbuf[i].description); if(len>tallen) { tallen = len; } } } fclose(logfile); } else { textEdit1->append("Can not open LBK file, will continue without events."); } tallen += 14; if(annot_cnt) { tallen += 14; } if(duration_present) { tallen += 14; } if(tallen%2) { tallen++; } /***************** write header *****************************************/ get_filename_from_path(outputfilename, path, MAX_PATH_LENGTH); remove_extension_from_filename(outputfilename); strcat(outputfilename, ".edf"); path[0] = 0; if(recent_savedir[0]!=0) { strcpy(path, recent_savedir); strcat(path, "/"); } strcat(path, outputfilename); strcpy(path, QFileDialog::getSaveFileName(0, "Output file", QString::fromLocal8Bit(path), "EDF files (*.edf *.EDF)").toLocal8Bit().data()); if(!strcmp(path, "")) { fclose(inputfile); free(logbuf); pushButton1->setEnabled(TRUE); return; } get_directory_from_path(recent_savedir, path, MAX_PATH_LENGTH); outputfile = fopen(path, "wb"); if(outputfile==NULL) { snprintf(txt_string, 2048, "Error, can not open file %s for writing.\n", path); textEdit1->append(QString::fromLocal8Bit(txt_string)); fclose(inputfile); free(logbuf); pushButton1->setEnabled(TRUE); return; } fprintf(outputfile, "0 "); i = fprintf(outputfile, "%05i %c %s %s%s%s", patientcode, gender, birthdate, patientname, handedness, weight); for(; i<80; i++) { fputc(' ', outputfile); } i = fprintf(outputfile, "Startdate %02i-%s-%04i %05i%02i X %s", atoi(date), month, year, patientcode, seq_nr, equipment); for(; i<80; i++) { fputc(' ', outputfile); } if(fwrite(date, 8, 1, outputfile)!=1) { textEdit1->append("Write error.\n"); fclose(inputfile); fclose(outputfile); free(logbuf); pushButton1->setEnabled(TRUE); return; } if(fwrite(time, 8, 1, outputfile)!=1) { textEdit1->append("Write error.\n"); fclose(inputfile); fclose(outputfile); free(logbuf); pushButton1->setEnabled(TRUE); return; } fprintf(outputfile, "%-8i", (256 * (channels + 2))); fprintf(outputfile, "EDF+C "); fprintf(outputfile, "%-8u", data_records); if(samplefrequency%10) { fprintf(outputfile, "1 "); } else { fprintf(outputfile, "0.1 "); } fprintf(outputfile, "%-4i", channels + 1); for(i=0; iappend("Write error.\n"); fclose(inputfile); fclose(outputfile); free(logbuf); pushButton1->setEnabled(TRUE); return; } } else { if(fwrite(scratchpad, 16, 1, outputfile)!=1) { textEdit1->append("Write error.\n"); fclose(inputfile); fclose(outputfile); free(logbuf); pushButton1->setEnabled(TRUE); return; } } } if(fwrite("EDF Annotations ", 16, 1, outputfile)!=1) { textEdit1->append("Write error.\n"); fclose(inputfile); fclose(outputfile); free(logbuf); pushButton1->setEnabled(TRUE); return; } for(i=0; i<(80*(channels+1)); i++) { fputc(' ', outputfile); } for(i=0; ibufsize) { bufsize = record_size; } buf = (char *)calloc(1, bufsize); if(buf==NULL) { textEdit1->append("Malloc error. (buf)\n"); fclose(inputfile); fclose(outputfile); free(logbuf); pushButton1->setEnabled(TRUE); return; } max_buf_records = bufsize / record_size; fseeko(inputfile, (long long)(hdrsize), SEEK_SET); while(data_records) { if(data_records>max_buf_records) records_in_buf = max_buf_records; else records_in_buf = data_records; for(i=0; i9) { deci_seconds = 0; seconds++; } } p[len++] = 20; p[len++] = 20; if(annots_writtenappend("Write error.\n"); fclose(inputfile); fclose(outputfile); free(buf); free(logbuf); pushButton1->setEnabled(TRUE); return; } data_records -= records_in_buf; } free(logbuf); free(buf); fclose(inputfile); fclose(outputfile); snprintf(txt_string, 2048, "Done, your EDF+ file is %s\n", path); textEdit1->append(QString::fromLocal8Bit(txt_string)); pushButton1->setEnabled(TRUE); } int UI_EMSA2EDFwindow::get_string(char *str, FILE *file, int offset, int maxlen) { int len; if(maxlen<1) { str[0] = 0; return(0); } fseeko(file, (long long)(offset), SEEK_SET); len = fgetc(file); if(len==EOF) { str[0] = 0; return(0); } if(len>maxlen) { len = maxlen; } if(fread(str, len, 1, file)!=1) { str[0] = 0; return(0); } str[len] = 0; return(len); } edfbrowser_153_source/PaxHeaders.2978/check_for_updates.h0000644000175000001440000000013212251654530021770 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/check_for_updates.h0000644000175000001440000000321012251654530021515 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef CHECKFORUPDATES_H #define CHECKFORUPDATES_H #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "utils.h" class Check_for_updates : public QObject { Q_OBJECT public: Check_for_updates(); private: QNetworkAccessManager *manager; private slots: void replyFinished(); }; #endif edfbrowser_153_source/PaxHeaders.2978/z_score_dialog.cpp0000644000175000001440000000013212251654530021636 xustar000000000000000030 mtime=1386699096.479032511 30 atime=1386699096.479032511 30 ctime=1386699096.479032511 edfbrowser_153_source/z_score_dialog.cpp0000644000175000001440000011144112251654530021371 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "z_score_dialog.h" #define ZSCORE_EPOCH_LEN 2 #define ZSCORE_F1 3.0 #define ZSCORE_F3 12.0 #define ZSCORE_F4 25.0 #define ZSCORE_ERRORLEVEL 5.0 UI_ZScoreWindow::UI_ZScoreWindow(QWidget *w_parent, UI_ZScoreWindow **w_zscoredialog, int w_zscore_dialognumber, int w_signalnr) { zscore_epoch_buf = NULL; zscore_page_buf = NULL; zscore_sleepstage_buf = NULL; crossoverfreq = 7.0; z_threshold = 0.0; zscore_page_len = 15; zscore_pages = 0; epoch_cntr = 0; zscore_wake = 1; mainwindow = (UI_Mainwindow *)w_parent; zscore_dialognumber = w_zscore_dialognumber; signalnr = w_signalnr; zscoredialog = w_zscoredialog; zscore_dialog_is_destroyed = 0; zscore_dialog = new QDialog(); zscore_dialog->setMinimumSize(600, 550); zscore_dialog->setWindowTitle("Z-EEG"); zscore_dialog->setModal(FALSE); zscore_dialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); zscore_dialog->setWindowIcon(QIcon(":/images/edf.png")); zscore_dialog->setSizeGripEnabled(TRUE); zscore_dialog->setWindowFlags(Qt::Window | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint); crossoverbinLabel = new QLabel; crossoverbinLabel->setMinimumSize(100, 25); crossoverbinLabel->setMaximumSize(100, 25); crossoverbinLabel->setText("Cross-over"); crossoverSpinbox = new QDoubleSpinBox; crossoverSpinbox->setMinimumSize(100, 25); crossoverSpinbox->setMaximumSize(100, 25); crossoverSpinbox->setRange(5.0, 9.5); crossoverSpinbox->setDecimals(1); crossoverSpinbox->setSingleStep(0.5); crossoverSpinbox->setSuffix(" Hz"); crossoverSpinbox->setValue(mainwindow->z_score_var.crossoverfreq); crossoverSpinbox->setToolTip("Threshold between low-frequency and high-frequency"); thresholdLabel = new QLabel; thresholdLabel->setMinimumSize(100, 25); thresholdLabel->setMaximumSize(100, 25); thresholdLabel->setText("Z-threshold"); thresholdSpinbox = new QDoubleSpinBox; thresholdSpinbox->setMinimumSize(100, 25); thresholdSpinbox->setMaximumSize(100, 25); thresholdSpinbox->setRange(-0.5, 0.5); thresholdSpinbox->setDecimals(2); thresholdSpinbox->setSingleStep(0.05); thresholdSpinbox->setValue(mainwindow->z_score_var.z_threshold); pagelenLabel = new QLabel; pagelenLabel->setMinimumSize(100, 25); pagelenLabel->setMaximumSize(100, 25); pagelenLabel->setText("Z-page"); pagelenSpinbox = new QSpinBox; pagelenSpinbox->setMinimumSize(100, 25); pagelenSpinbox->setMaximumSize(100, 25); pagelenSpinbox->setRange(10, 60); pagelenSpinbox->setSingleStep(2); pagelenSpinbox->setSuffix(" sec"); pagelenSpinbox->setValue(mainwindow->z_score_var.zscore_page_len); // errordetectionLabel = new QLabel; // errordetectionLabel->setMinimumSize(100, 25); // errordetectionLabel->setMaximumSize(100, 25); // errordetectionLabel->setText("Error detection"); // // errordetectionSpinbox = new QSpinBox; // errordetectionSpinbox->setMinimumSize(100, 25); // errordetectionSpinbox->setMaximumSize(100, 25); // errordetectionSpinbox->setRange(50, 100); // errordetectionSpinbox->setSingleStep(1); // errordetectionSpinbox->setSuffix(" \%"); // errordetectionSpinbox->setValue(mainwindow->z_score_var.zscore_error_detection); // errordetectionSpinbox->setToolTip("Enter value of \% total power when any of the four\n" // "standard bandwidths: delta, theta, alpha, beta\n" // "exceeds this percent of total power.\n" // "This value will be evaluated when annotating."); hysteresisLabel = new QLabel; hysteresisLabel->setMinimumSize(100, 25); hysteresisLabel->setMaximumSize(100, 25); hysteresisLabel->setText("Sleep/Wake\ndifferentiation"); hysteresisSpinbox = new QDoubleSpinBox; hysteresisSpinbox->setMinimumSize(100, 25); hysteresisSpinbox->setMaximumSize(100, 25); hysteresisSpinbox->setDecimals(2); hysteresisSpinbox->setRange(0.0, 0.25); hysteresisSpinbox->setSingleStep(0.01); hysteresisSpinbox->setValue(mainwindow->z_score_var.z_hysteresis); hysteresisSpinbox->setToolTip("Hysteresis applied to the z-threshold."); curve1 = new SignalCurve; curve1->setSignalColor(Qt::green); curve1->setBackgroundColor(Qt::black); curve1->setRasterColor(Qt::gray); curve1->setCrosshairColor(Qt::red); curve1->setTraceWidth(0); curve1->setDashBoardEnabled(FALSE); curve1->setUpsidedownEnabled(TRUE); StartButton = new QPushButton; StartButton->setMinimumSize(100, 25); StartButton->setMaximumSize(100, 25); StartButton->setText("Calculate"); StartButton->setToolTip("Plot the Z-ratio / Z-pages"); jumpButton = new QPushButton; jumpButton->setMinimumSize(100, 25); jumpButton->setMaximumSize(100, 25); jumpButton->setText("Jump"); jumpButton->setToolTip("Jump to cursor-position"); get_annotButton = new QPushButton; get_annotButton->setMinimumSize(100, 25); get_annotButton->setMaximumSize(100, 25); get_annotButton->setText("Annotate"); get_annotButton->setToolTip("Create annotations from the Z-EEG"); defaultButton = new QPushButton; defaultButton->setMinimumSize(100, 25); defaultButton->setMaximumSize(100, 25); defaultButton->setText("Default"); defaultButton->setToolTip("Set parameters to default values"); CloseButton = new QPushButton; CloseButton->setMinimumSize(100, 25); CloseButton->setMaximumSize(100, 25); CloseButton->setText("Close"); CloseButton->setToolTip("Close this window"); addTraceButton = new QPushButton; addTraceButton->setMinimumSize(100, 25); addTraceButton->setMaximumSize(100, 25); addTraceButton->setText("Add Trace"); addTraceButton->setToolTip("Add this Z-ratio trace to the mainwindow"); epochRadioButton = new QRadioButton; epochRadioButton->setMinimumSize(100, 25); epochRadioButton->setMaximumSize(100, 25); epochRadioButton->setText("Epochs"); pageRadioButton = new QRadioButton; pageRadioButton->setMinimumSize(100, 25); pageRadioButton->setMaximumSize(100, 25); pageRadioButton->setText("Pages"); wakesleepRadioButton = new QRadioButton; wakesleepRadioButton->setMinimumSize(100, 25); wakesleepRadioButton->setMaximumSize(100, 25); wakesleepRadioButton->setText("Sleep/Wake"); pageRadioButton->setChecked(TRUE); plot_type = 1; hlayout1 = new QHBoxLayout; hlayout1->setSpacing(20); hlayout1->addWidget(crossoverbinLabel); hlayout1->addWidget(crossoverSpinbox); hlayout1->addStretch(100); hlayout1->addWidget(epochRadioButton); hlayout1->addStretch(100); hlayout1->addWidget(StartButton); hlayout2 = new QHBoxLayout; hlayout2->setSpacing(20); hlayout2->addWidget(thresholdLabel); hlayout2->addWidget(thresholdSpinbox); hlayout2->addStretch(100); hlayout2->addWidget(pageRadioButton); hlayout2->addStretch(100); hlayout2->addWidget(jumpButton); hlayout3 = new QHBoxLayout; hlayout3->setSpacing(20); hlayout3->addWidget(pagelenLabel); hlayout3->addWidget(pagelenSpinbox); hlayout3->addStretch(100); hlayout3->addWidget(wakesleepRadioButton); hlayout3->addStretch(100); hlayout3->addWidget(get_annotButton); // hlayout4 = new QHBoxLayout; // hlayout4->setSpacing(20); // hlayout4->addWidget(errordetectionLabel); // hlayout4->addWidget(errordetectionSpinbox); // hlayout4->addStretch(100); hlayout4 = new QHBoxLayout; hlayout4->setSpacing(20); hlayout4->addStretch(100); hlayout4->addWidget(addTraceButton); hlayout5 = new QHBoxLayout; hlayout5->setSpacing(20); hlayout5->addWidget(hysteresisLabel); hlayout5->addWidget(hysteresisSpinbox); hlayout5->addStretch(100); hlayout5->addWidget(defaultButton); hlayout5->addStretch(100); hlayout5->addWidget(CloseButton); vlayout2 = new QVBoxLayout; vlayout2->setSpacing(20); vlayout2->addLayout(hlayout1); vlayout2->addLayout(hlayout2); vlayout2->addLayout(hlayout3); vlayout2->addLayout(hlayout4); vlayout2->addLayout(hlayout5); vlayout3 = new QVBoxLayout; vlayout3->setSpacing(20); vlayout3->setContentsMargins(20, 20, 20, 20); vlayout3->addWidget(curve1); vlayout3->addLayout(vlayout2); zscore_dialog->setLayout(vlayout3); shift_page_left_Act = new QAction(this); shift_page_left_Act->setShortcut(QKeySequence::MoveToPreviousChar); connect(shift_page_left_Act, SIGNAL(triggered()), this, SLOT(shift_page_left())); zscore_dialog->addAction(shift_page_left_Act); shift_page_right_Act = new QAction(this); shift_page_right_Act->setShortcut(QKeySequence::MoveToNextChar); connect(shift_page_right_Act, SIGNAL(triggered()), this, SLOT(shift_page_right())); zscore_dialog->addAction(shift_page_right_Act); QObject::connect(CloseButton, SIGNAL(clicked()), zscore_dialog, SLOT(close())); QObject::connect(StartButton, SIGNAL(clicked()), this, SLOT(startButtonClicked())); QObject::connect(get_annotButton, SIGNAL(clicked()), this, SLOT(get_annotationsButtonClicked())); QObject::connect(jumpButton, SIGNAL(clicked()), this, SLOT(jumpButtonClicked())); QObject::connect(zscore_dialog, SIGNAL(destroyed(QObject *)), this, SLOT(ZscoreDialogDestroyed(QObject *))); QObject::connect(epochRadioButton, SIGNAL(clicked(bool)), this, SLOT(RadioButtonsClicked(bool))); QObject::connect(pageRadioButton, SIGNAL(clicked(bool)), this, SLOT(RadioButtonsClicked(bool))); QObject::connect(wakesleepRadioButton, SIGNAL(clicked(bool)), this, SLOT(RadioButtonsClicked(bool))); QObject::connect(defaultButton, SIGNAL(clicked()), this, SLOT(defaultButtonClicked())); QObject::connect(curve1, SIGNAL(markerHasMoved()), this, SLOT(markersMoved())); QObject::connect(addTraceButton, SIGNAL(clicked()), this, SLOT(addTraceButtonClicked())); zscore_dialog->show(); } UI_ZScoreWindow::~UI_ZScoreWindow() { if(!zscore_dialog_is_destroyed) { zscore_dialog->close(); } if(zscore_epoch_buf != NULL) { free(zscore_epoch_buf); } if(zscore_page_buf != NULL) { free(zscore_page_buf); } if(zscore_sleepstage_buf != NULL) { free(zscore_sleepstage_buf); } zscoredialog[zscore_dialognumber] = NULL; } void UI_ZScoreWindow::ZscoreDialogDestroyed(QObject *) { zscore_dialog_is_destroyed = 1; zscoredialog[zscore_dialognumber] = NULL; delete this; } void UI_ZScoreWindow::addTraceButtonClicked() { int i; struct edfhdrblock *hdr; struct signalcompblock *signalcomp, *original_signalcomp; original_signalcomp = mainwindow->signalcomp[signalnr]; hdr = original_signalcomp->edfhdr; if(original_signalcomp->ecg_filter != NULL) { return; } if(original_signalcomp->zratio_filter != NULL) { return; } signalcomp = mainwindow->create_signalcomp_copy(original_signalcomp); if(signalcomp == NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Internal error: can not create a signalcomp copy."); messagewindow.exec(); return; } signalcomp->zratio_filter = create_zratio_filter(hdr->edfparam[signalcomp->edfsignal[0]].smp_per_record, hdr->long_data_record_duration, crossoverSpinbox->value(), signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].bitvalue); if(signalcomp->zratio_filter == NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not create a Z-ratio-filter, malloc() error?"); messagewindow.exec(); free(signalcomp); return; } strcpy(signalcomp->signallabel_bu, signalcomp->signallabel); signalcomp->signallabellen_bu = signalcomp->signallabellen; strcpy(signalcomp->signallabel, "Z-ratio "); strcat(signalcomp->signallabel, signalcomp->signallabel_bu); signalcomp->signallabellen = strlen(signalcomp->signallabel); strcpy(signalcomp->physdimension_bu, signalcomp->physdimension); strcpy(signalcomp->physdimension, ""); signalcomp->polarity = -1; if(signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].bitvalue < 0.0) { for(i=0; inum_of_signals; i++) { signalcomp->sensitivity[i] = signalcomp->edfhdr->edfparam[signalcomp->edfsignal[i]].bitvalue / -1.0 / mainwindow->pixelsizefactor; } signalcomp->voltpercm = -1.0; } else { for(i=0; inum_of_signals; i++) { signalcomp->sensitivity[i] = signalcomp->edfhdr->edfparam[signalcomp->edfsignal[i]].bitvalue / 1.0 / mainwindow->pixelsizefactor; } signalcomp->voltpercm = 1.0; } signalcomp->zratio_crossoverfreq = crossoverSpinbox->value(); signalcomp->screen_offset = 0.0; mainwindow->setup_viewbuf(); } void UI_ZScoreWindow::defaultButtonClicked() { pagelenSpinbox->setValue(30); // errordetectionSpinbox->setValue(80); thresholdSpinbox->setValue(0.0); crossoverSpinbox->setValue(7.5); hysteresisSpinbox->setValue(0.0); } void UI_ZScoreWindow::startButtonClicked() { int i, datrec_offset, total_datrecs, smpls, smp_per_record, smpls_in_epoch, dftblocksize, fft_outputbufsize, smpls_in_inputbuf, smpls_copied, epochs, f1, f2, f3, f4, power_neg_cnt, power_pos_cnt, progress_steps; double *buf, *fft_inputbuf, *fft_outputbuf, samplefreq, freqstep, power_delta, power_theta, power_alpha, power_beta, power_total, power_neg, power_pos; struct edfhdrblock *hdr; struct signalcompblock *signalcomp; crossoverfreq = crossoverSpinbox->value(); mainwindow->z_score_var.crossoverfreq = crossoverfreq; z_threshold = thresholdSpinbox->value(); mainwindow->z_score_var.z_threshold = z_threshold; zscore_page_len = pagelenSpinbox->value() / 2; mainwindow->z_score_var.zscore_page_len = zscore_page_len * 2; // zscore_error_detection = errordetectionSpinbox->value(); // mainwindow->z_score_var.zscore_error_detection = zscore_error_detection; z_hysteresis = hysteresisSpinbox->value(); mainwindow->z_score_var.z_hysteresis = z_hysteresis; z_hysteresis /= 2.0; signalcomp = mainwindow->signalcomp[signalnr]; hdr = signalcomp->edfhdr; total_datrecs = hdr->datarecords; smp_per_record = hdr->edfparam[signalcomp->edfsignal[0]].smp_per_record; dftblocksize = ((long long)smp_per_record * (ZSCORE_EPOCH_LEN * TIME_DIMENSION)) / hdr->long_data_record_duration; if(dftblocksize < (ZSCORE_EPOCH_LEN * 100)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Samplerate of selected signal is too low"); messagewindow.exec(); curve1->clear(); return; } smpls_in_epoch = dftblocksize; epochs = (hdr->datarecords * (long long)smp_per_record) / (long long)smpls_in_epoch; samplefreq = (double)smp_per_record / ((double)hdr->long_data_record_duration / TIME_DIMENSION); if(samplefreq < 99.9999999) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Samplefrequency of the selected signal must be at least 100 Hz."); messagewindow.exec(); curve1->clear(); return; } fft_outputbufsize = dftblocksize / 2; freqstep = samplefreq / (double)dftblocksize; if(freqstep > 1.0001) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Frequency bin of FFT is more than 1 Hz."); messagewindow.exec(); curve1->clear(); return; } f2 = crossoverfreq / freqstep; f1 = ZSCORE_F1 / freqstep; f3 = ZSCORE_F3 / freqstep; f4 = ZSCORE_F4 / freqstep; fft_inputbuf = (double *)malloc(sizeof(double) * dftblocksize); if(fft_inputbuf == NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "The system was not able to provide enough resources (memory) to perform the requested action."); messagewindow.exec(); curve1->clear(); return; } fft_outputbuf = (double *)calloc(1, sizeof(double) * fft_outputbufsize); if(fft_outputbuf == NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "The system was not able to provide enough resources (memory) to perform the requested action."); messagewindow.exec(); curve1->clear(); free(fft_inputbuf); return; } if(zscore_epoch_buf != NULL) { free(zscore_epoch_buf); } zscore_epoch_buf = (double *)calloc(1, sizeof(double) * epochs); if(zscore_epoch_buf == NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "The system was not able to provide enough resources (memory) to perform the requested action."); messagewindow.exec(); curve1->clear(); free(fft_inputbuf); free(fft_outputbuf); return; } if(zscore_page_buf != NULL) { free(zscore_page_buf); } zscore_page_buf = (double *)calloc(1, sizeof(double) * ((epochs / zscore_page_len) + 1)); if(zscore_page_buf == NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "The system was not able to provide enough resources (memory) to perform the requested action."); messagewindow.exec(); curve1->clear(); free(fft_inputbuf); free(fft_outputbuf); return; } if(zscore_sleepstage_buf != NULL) { free(zscore_sleepstage_buf); } zscore_sleepstage_buf = (int *)calloc(1, sizeof(int) * ((epochs / zscore_page_len) + 1)); if(zscore_sleepstage_buf == NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "The system was not able to provide enough resources (memory) to perform the requested action."); messagewindow.exec(); curve1->clear(); free(fft_inputbuf); free(fft_outputbuf); return; } // printf("epochs / zscore_page_len is %i\n", // epochs / zscore_page_len); kiss_fftr_cfg cfg; kiss_fft_cpx *kiss_fftbuf; kiss_fftbuf = (kiss_fft_cpx *)malloc((fft_outputbufsize + 1) * sizeof(kiss_fft_cpx)); if(kiss_fftbuf == NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "The system was not able to provide enough resources (memory) to perform the requested action."); messagewindow.exec(); curve1->clear(); free(fft_inputbuf); free(fft_outputbuf); return; } cfg = kiss_fftr_alloc(dftblocksize, 0, NULL, NULL); FilteredBlockReadClass blockread; buf = blockread.init_signalcomp(signalcomp, 1, 0); if(buf == NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Internal error: init_signalcomp()"); messagewindow.exec(); curve1->clear(); free(fft_inputbuf); free(fft_outputbuf); free(cfg); free(kiss_fftbuf); return; } QProgressDialog progress("Processing ...", "Abort", 0, (int)hdr->datarecords, zscore_dialog); progress.setWindowModality(Qt::WindowModal); progress.setMinimumDuration(200); progress_steps = total_datrecs / 100; if(progress_steps < 1) { progress_steps = 1; } if(progress_steps > 50) { progress_steps = 50; } // printf("total_datrecs is %i\n" // "smp_per_record is %i\n" // "dftblocksize is %i\n" // "smpls_in_epoch is %i\n" // "epochs is %i\n" // "samplefreq is %f\n" // "fft_outputbufsize is %i\n" // "freqstep is %f\n" // "f1 is %i\n" // "f2 is %i\n" // "f3 is %i\n" // "f4 is %i\n" // "z_hysteresis is %f\n", // total_datrecs, // smp_per_record, // dftblocksize, // smpls_in_epoch, // epochs, // samplefreq, // fft_outputbufsize, // freqstep, // f1, // f2, // f3, // f4, // z_hysteresis); epoch_cntr = 0; smpls_in_inputbuf = 0; // FILE *test_file1 = fopen("testfile1.dat", "wb"); // if(test_file1 == NULL) // { // printf("error opening file\n"); // return; // } // // FILE *test_file2 = fopen("testfile2.dat", "wb"); // if(test_file2 == NULL) // { // printf("error opening file\n"); // return; // } for(datrec_offset=0; datrec_offset < total_datrecs; datrec_offset++) // for(datrec_offset=0; datrec_offset < 2; datrec_offset++) { // printf("\ndatrec_offset is %i\n", datrec_offset); // printf("smpls_in_inputbuf is %i\n", smpls_in_inputbuf); if(!(datrec_offset % progress_steps)) { progress.setValue(datrec_offset); qApp->processEvents(); if(progress.wasCanceled() == TRUE) { break; } } if(blockread.process_signalcomp(datrec_offset)) { progress.reset(); QMessageBox messagewindow(QMessageBox::Critical, "Error", "A read-error occurred."); messagewindow.exec(); curve1->clear(); free(fft_inputbuf); free(fft_outputbuf); free(cfg); free(kiss_fftbuf); return; } smpls = blockread.samples_in_buf(); // fwrite(buf, smpls * sizeof(double), 1, test_file1); // printf("smpls is %i\n", smpls); // for(k=0; k 0) { // printf("while(smpls > 0)\n"); if(smpls < (dftblocksize - smpls_in_inputbuf)) { memcpy(fft_inputbuf + smpls_in_inputbuf, buf, smpls * sizeof(double)); // for(j=0; j 0) && (i < f1)) { power_delta += fft_outputbuf[i]; } if((i >= f1) && (i < f2)) { power_theta += fft_outputbuf[i]; } if((i >= f2) && (i < f3)) { power_alpha += fft_outputbuf[i]; } if((i >= f3) && (i <= f4)) { power_beta += fft_outputbuf[i]; } power_total += fft_outputbuf[i]; } if(power_total <= 0.0) { zscore_epoch_buf[epoch_cntr++] = 0.0; } else { zscore_epoch_buf[epoch_cntr++] = ((power_delta + power_theta) - (power_alpha + power_beta)) / power_total; } // if(epoch_cntr < 3) // { // printf("zscore_epoch_buf[%i] is %f\n", epoch_cntr - 1, zscore_epoch_buf[epoch_cntr - 1]); // printf("power_delta is %f\n" // "power_theta is %f\n" // "power_alpha is %f\n" // "power_beta is %f\n" // "power_total is %f\n\n", // power_delta, power_theta, power_alpha, power_beta, power_total); // } if(epoch_cntr >= epochs) { break; } } if(epoch_cntr >= epochs) { break; } } power_pos = 0.0; power_neg = 0.0; power_pos_cnt = 0; power_neg_cnt = 0; zscore_pages = 0; for(i=0; i= power_pos_cnt) { zscore_page_buf[zscore_pages] = power_neg; zscore_sleepstage_buf[zscore_pages] = 0; } else { zscore_page_buf[zscore_pages] = power_pos; zscore_sleepstage_buf[zscore_pages] = 1; } zscore_pages++; power_pos = 0.0; power_neg = 0.0; power_pos_cnt = 0; power_neg_cnt = 0; } if(zscore_epoch_buf[i] < ZSCORE_ERRORLEVEL) { if(zscore_pages > 0) { if(zscore_sleepstage_buf[zscore_pages - 1] == 0) { // printf("if(zscore_sleepstage_buf[zscore_pages - 1] == 0) : %f < %f + %f\n", // zscore_epoch_buf[i], z_threshold, z_hysteresis); if(zscore_epoch_buf[i] < (z_threshold + z_hysteresis)) { power_neg += zscore_epoch_buf[i]; power_neg_cnt++; } else { power_pos += zscore_epoch_buf[i]; power_pos_cnt++; } } else { // printf("else : %f < %f + %f\n", // zscore_epoch_buf[i], z_threshold, z_hysteresis); if(zscore_epoch_buf[i] < (z_threshold - z_hysteresis)) { power_neg += zscore_epoch_buf[i]; power_neg_cnt++; } else { power_pos += zscore_epoch_buf[i]; power_pos_cnt++; } } } else { if(zscore_epoch_buf[i] < z_threshold) { power_neg += zscore_epoch_buf[i]; power_neg_cnt++; } else { power_pos += zscore_epoch_buf[i]; power_pos_cnt++; } } } } // printf("epoch_cntr is %i zscore_pages is %i\n", // epoch_cntr, zscore_pages); // Delta: 0.5 - 2.0 Hz // Theta: 2.5 - 7.0 Hz // Alpha: 7.5 - 11.5 Hz // Beta: 12.0 - 25.0 Hz // Stage Z ratio (mean +-SD) // ---------------------------- // Wake -0.181 +- .055 // REM 0.156 +- .043 // 1 0.066 +- .101 // 2 0.207 +- .067 // 3 0.443 +- .034 // 4 0.527 +- .039 // ZRatio = ((Delta + Theta) - (Alpha + Beta)) / (Delta + Theta + Alpha + Beta) progress.reset(); RadioButtonsClicked(TRUE); free(fft_inputbuf); free(fft_outputbuf); free(cfg); free(kiss_fftbuf); mainwindow->setup_viewbuf(); // printf("epoch_cntr is %i epochs is %i\n", epoch_cntr, epochs); // fclose(test_file1); // fclose(test_file2); } void UI_ZScoreWindow::get_annotationsButtonClicked() { int i, awake = 1, filenum, marker_start, marker_end; struct annotationblock *annotation; if((epoch_cntr < 2) || (zscore_pages < 1)) { return; } marker_start = curve1->getMarker1Position() * zscore_pages; if(marker_start < 0) { marker_start = 0; } marker_end = curve1->getMarker2Position() * zscore_pages; if(marker_end > zscore_pages) { marker_end = zscore_pages; } filenum = mainwindow->signalcomp[signalnr]->edfhdr->file_num; for(i=0; i= marker_start) { annotation = (struct annotationblock *)calloc(1, sizeof(struct annotationblock)); if(annotation == NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "A memory allocation error occurred (annotation)."); messagewindow.exec(); return; } annotation->onset = i * zscore_page_len * 2LL * TIME_DIMENSION; if(awake) { strcpy(annotation->annotation, "Wake"); } else { strcpy(annotation->annotation, "Sleep"); } edfplus_annotation_add_item(&mainwindow->annotationlist[filenum], annotation); } } } if(mainwindow->annotations_dock[filenum] == NULL) { mainwindow->annotations_dock[filenum] = new UI_Annotationswindow(filenum, mainwindow); mainwindow->addDockWidget(Qt::RightDockWidgetArea, mainwindow->annotations_dock[filenum]->docklist, Qt::Vertical); if(!mainwindow->annotationlist[filenum]) { mainwindow->annotations_dock[filenum]->docklist->hide(); } } if(mainwindow->annotationlist[filenum]) { mainwindow->annotations_dock[filenum]->docklist->show(); mainwindow->annotations_edited = 1; mainwindow->annotations_dock[filenum]->updateList(); mainwindow->save_act->setEnabled(TRUE); } mainwindow->maincurve->update(); } void UI_ZScoreWindow::RadioButtonsClicked(bool) { int i, marker_start, marker_end, regression_samples, sleep_cnt, sleep_pct; double b0, b1, sum_xy=0.0, sum_x2=0.0, avg_x=0.0, avg_y=0.0, shiftfactor=2.0; char str[1024]; if(epochRadioButton->isChecked() == TRUE) { plot_type = 0; if((epoch_cntr < 2) || (zscore_pages < 1)) { return; } marker_start = curve1->getMarker1Position() * epoch_cntr; if(marker_start < 0) { marker_start = 0; } marker_end = curve1->getMarker2Position() * epoch_cntr; if(marker_end > epoch_cntr) { marker_end = epoch_cntr; } regression_samples = marker_end - marker_start; if(regression_samples < 60) { return; } for(i=0; isignalcomp[signalnr]->signallabel, b1, b0); curve1->drawCurve(zscore_epoch_buf, epoch_cntr, 1.0, -1.0); curve1->setH_RulerValues(0, epoch_cntr); curve1->setLowerLabel("Epochs"); curve1->setV_label("Z ratio"); curve1->setUpperLabel1(str); curve1->drawLine(marker_start, b0 + b1, marker_end, b0 + (b1 * regression_samples), Qt::yellow); curve1->setMarker1Enabled(TRUE); curve1->setMarker1MovableEnabled(TRUE); curve1->setMarker2Enabled(TRUE); curve1->setMarker2MovableEnabled(TRUE); } if(pageRadioButton->isChecked() == TRUE) { plot_type = 1; if((epoch_cntr < 2) || (zscore_pages < 1)) { return; } marker_start = curve1->getMarker1Position() * zscore_pages; if(marker_start < 0) { marker_start = 0; } marker_end = curve1->getMarker2Position() * zscore_pages; if(marker_end > zscore_pages) { marker_end = zscore_pages; } regression_samples = marker_end - marker_start; if(regression_samples < 2) { return; } for(i=0; isignalcomp[signalnr]->signallabel, b1, b0); curve1->drawCurve(zscore_page_buf, zscore_pages, 1.0, -1.0); curve1->setH_RulerValues(0, zscore_pages); curve1->setLowerLabel("Pages"); curve1->setV_label("Z ratio"); curve1->setUpperLabel1(str); curve1->drawLine(marker_start, b0 + b1, marker_end, b0 + (b1 * regression_samples), Qt::yellow); curve1->setMarker1Enabled(TRUE); curve1->setMarker1MovableEnabled(TRUE); curve1->setMarker2Enabled(TRUE); curve1->setMarker2MovableEnabled(TRUE); } if(wakesleepRadioButton->isChecked() == TRUE) { plot_type = 2; if((epoch_cntr < 2) || (zscore_pages < 1)) { return; } marker_start = curve1->getMarker1Position() * zscore_pages; if(marker_start < 0) { marker_start = 0; } marker_end = curve1->getMarker2Position() * zscore_pages; if(marker_end > zscore_pages) { marker_end = zscore_pages; } regression_samples = marker_end - marker_start; if(regression_samples < 2) { return; } sleep_cnt = 0; for(i=marker_start; isignalcomp[signalnr]->signallabel, sleep_pct); curve1->drawCurve(zscore_sleepstage_buf, zscore_pages, 3.0, -3.0); curve1->setH_RulerValues(0, zscore_pages); curve1->setLowerLabel("Pages"); curve1->setV_label("Sleep/Wake"); curve1->setUpperLabel1(str); curve1->setLineEnabled(FALSE); curve1->setMarker1Enabled(TRUE); curve1->setMarker1MovableEnabled(TRUE); curve1->setMarker2Enabled(TRUE); curve1->setMarker2MovableEnabled(TRUE); } } void UI_ZScoreWindow::markersMoved() { RadioButtonsClicked(TRUE); } void UI_ZScoreWindow::jumpButtonClicked() { int i, file_num; long long onset, temp; double position; if((epoch_cntr < 2) || (zscore_pages < 1)) { return; } if(curve1->isCursorActive() == FALSE) { return; } position = curve1->getCursorPosition(); if(plot_type) { onset = position * zscore_page_len * 2 * TIME_DIMENSION; } else { onset = position * ZSCORE_EPOCH_LEN * TIME_DIMENSION; } file_num = mainwindow->signalcomp[signalnr]->edfhdr->file_num; if(mainwindow->viewtime_sync==VIEWTIME_SYNCED_OFFSET) { for(i=0; ifiles_open; i++) { mainwindow->edfheaderlist[i]->viewtime = onset; mainwindow->edfheaderlist[i]->viewtime -= (mainwindow->pagetime / 2); mainwindow->edfheaderlist[i]->viewtime -= mainwindow->edfheaderlist[file_num]->starttime_offset; } } if(mainwindow->viewtime_sync==VIEWTIME_UNSYNCED) { mainwindow->edfheaderlist[file_num]->viewtime = onset; mainwindow->edfheaderlist[file_num]->viewtime -= (mainwindow->pagetime / 2); mainwindow->edfheaderlist[file_num]->viewtime -= mainwindow->edfheaderlist[file_num]->starttime_offset; } if((mainwindow->viewtime_sync==VIEWTIME_SYNCED_ABSOLUT)||(mainwindow->viewtime_sync==VIEWTIME_USER_DEF_SYNCED)) { temp = onset - mainwindow->edfheaderlist[file_num]->viewtime; temp -= mainwindow->edfheaderlist[file_num]->starttime_offset; temp -= (mainwindow->pagetime / 2); for(i=0; ifiles_open; i++) { mainwindow->edfheaderlist[i]->viewtime += temp; } } mainwindow->setup_viewbuf(); } void UI_ZScoreWindow::shift_page_right() { if((epoch_cntr < 2) || (zscore_pages < 1)) { return; } if(curve1->isCursorActive() == FALSE) { return; } curve1->shiftCursorIndexRight(1); } void UI_ZScoreWindow::shift_page_left() { if((epoch_cntr < 2) || (zscore_pages < 1)) { return; } if(curve1->isCursorActive() == FALSE) { return; } curve1->shiftCursorIndexLeft(1); } edfbrowser_153_source/PaxHeaders.2978/viewcurve.h0000644000175000001440000000013212251654530020337 xustar000000000000000030 mtime=1386699096.468032569 30 atime=1386699096.468032569 30 ctime=1386699096.468032569 edfbrowser_153_source/viewcurve.h0000644000175000001440000001525512251654530020100 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef VIEWCURVE_H #define VIEWCURVE_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "mainwindow.h" #include "colordialog.h" #include "filter.h" #include "popup_messagewindow.h" #include "spectrumanalyzer.h" #include "utils.h" #include "adjustfiltersettings.h" #include "ravg_filter.h" #include "ecg_filter.h" #include "statistics_dialog.h" #include "z_score_dialog.h" #include "z_ratio_filter.h" #include "third_party/fidlib/fidlib.h" class UI_Mainwindow; class drawCurve_stage_1_thread : public QThread { public: void init_vars(UI_Mainwindow *, struct signalcompblock **, int, int, char *, int, int, int *, int, struct graphicBufStruct *, double, double, struct crossHairStruct *, struct crossHairStruct *, int); private: int i, h, w, signalcomps, *screensamples, *screensamples_b, printing, cpu_cnt; char *viewbuf; double printsize_x_factor, printsize_y_factor; UI_Mainwindow *mainwindow; struct signalcompblock *signalcomp, **signalcomp_b; struct graphicBufStruct *graphicBuf; struct crossHairStruct *crosshair_1, *crosshair_2; void run(); }; class ViewCurve : public QWidget { Q_OBJECT public: ViewCurve(QWidget *parent=0); ~ViewCurve(); UI_Mainwindow *mainwindow; int use_move_events, mouse_x, mouse_y, mouse_old_x, mouse_old_y, sidemenu_active, signal_nr, mouse_press_coordinate_x, mouse_press_coordinate_y, draw_zoom_rectangle, signal_color, floating_ruler_color, ruler_active, ruler_moving, ruler_x_position, ruler_y_position, *screensamples, graphicBufWidth, blackwhite_printing, backup_color_10[MAXSIGNALS], backup_color_11, backup_color_12, backup_color_14, annot_marker_moving, pressed_on_label, label_press_y_position, cpu_cnt, floating_ruler_value; double original_screen_offset; struct graphicBufStruct *graphicBuf, *printBuf; struct active_markersblock *active_markers; struct crossHairStruct crosshair_1, crosshair_2; QColor backgroundcolor, small_ruler_color, big_ruler_color, mouse_rect_color, baseline_color, text_color, annot_marker_color, backup_color_1, backup_color_2, backup_color_3, backup_color_4, backup_color_5, backup_color_13, backup_color_15; QFont *printfont; void drawCurve_stage_1(QPainter *painter=NULL, int w_width=0, int w_height=0, int print_linewidth=0); void setCrosshair_1_center(void); public slots: void exec_sidemenu(int); void print_to_postscript(); void print_to_pdf(); void print_to_image(int, int); void print_to_printer(); private: QDialog *sidemenu; QPushButton *sidemenuButton1, *sidemenuButton2, *sidemenuButton3, *sidemenuButton4, *sidemenuButton5, *sidemenuButton6, *sidemenuButton7, *sidemenuButton8, *sidemenuButton9, *sidemenuButton10, *sidemenuButton11, *sidemenuButton12, *sidemenuButton13; QDoubleSpinBox *ScaleBox, *ScaleBox2; QLabel *SidemenuLabel, *AmpLabel, *AliasLabel, *OffsetLabel; QLineEdit *AliasLineEdit; QPrinter *printer; QPen *special_pen, *annot_marker_pen, *signal_pen, *ruler_pen; int printing, w, h; double *original_sensitivity, painter_pixelsizefactor, printsize_x_factor, printsize_y_factor; drawCurve_stage_1_thread *thr[MAXSIGNALS]; inline void floating_ruler(QPainter *, int, int, struct signalcompblock *, int); void backup_colors_for_printing(void); void restore_colors_after_printing(void); protected slots: void RulerButton(); void FittopaneButton(); void ScaleBoxChanged(double); void ScaleBox2Changed(double); void RemovefilterButton(); void RemovesignalButton(); void ColorButton(); void CrosshairButton(); void FreqSpecButton(); void Z_scoringButton(); void AdjustFilterButton(); void StatisticsButton(); void ECGdetectButton(); void signalInvert(); void strip_types_from_label(char *); void sidemenu_close(); protected: void paintEvent(QPaintEvent *); void resizeEvent(QResizeEvent *); void drawCurve_stage_2(QPainter *painter, int w_width=0, int w_height=0, int print_linewidth=0); void mousePressEvent(QMouseEvent *); void mouseReleaseEvent(QMouseEvent *); void mouseMoveEvent(QMouseEvent *); void wheelEvent(QWheelEvent *); }; #endif edfbrowser_153_source/PaxHeaders.2978/wav2edf.h0000644000175000001440000000013212251654530017656 xustar000000000000000030 mtime=1386699096.468032569 30 atime=1386699096.468032569 30 ctime=1386699096.468032569 edfbrowser_153_source/wav2edf.h0000644000175000001440000000451312251654530017412 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef UI_WAV2EDFFORM_H #define UI_WAV2EDFFORM_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "popup_messagewindow.h" #include "utils.h" #include "edflib.h" class UI_WAV2EDFwindow : public QObject { Q_OBJECT public: UI_WAV2EDFwindow(char *recent_dir=NULL, char *save_dir=NULL); private: QDialog *myobjectDialog; QPushButton *pushButton1, *pushButton2; QLabel *PatientnameLabel, *RecordingLabel, *DatetimeLabel, *PhysDimLabel, *PhysMaxLabel; QLineEdit *PatientnameLineEdit, *RecordingLineEdit, *PhysDimLineEdit; QDateTimeEdit *StartDatetimeedit; QDoubleSpinBox *PhysMaxSpinBox; char *recent_opendir, *recent_savedir; void enable_widgets(bool); private slots: void SelectFileButton(); }; #endif edfbrowser_153_source/PaxHeaders.2978/xml.cpp0000644000175000001440000000013212251654530017453 xustar000000000000000030 mtime=1386699096.479032511 30 atime=1386699096.479032511 30 ctime=1386699096.479032511 edfbrowser_153_source/xml.cpp0000644000175000001440000005576112251654530017222 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "xml.h" int next_tag(int, struct xml_handle *); int process_tag(const char *, struct xml_handle *); int xml_attribute(const char *, const char *, char *, int); int xml_character_encoding_type(struct xml_handle *handle_p) { if(handle_p==NULL) return(-1); return(handle_p->encoding); } void xml_fwrite_encode_entity(FILE *file, const char *str) { for(; *str; str++) { switch(*str) { case '<' : fwrite("<", 4, 1, file); break; case '>' : fwrite(">", 4, 1, file); break; case '&' : fwrite("&", 5, 1, file); break; case '\'' : fwrite("'", 6, 1, file); break; case '\"' : fwrite(""", 6, 1, file); break; default : fputc(*str, file); break; } } } void xml_fnwrite_encode_entity(FILE *file, const char *str, int n) { int i; for(i=0; i' : fwrite(">", 4, 1, file); break; case '&' : fwrite("&", 5, 1, file); break; case '\'' : fwrite("'", 6, 1, file); break; case '\"' : fwrite(""", 6, 1, file); break; default : fputc(str[i], file); break; } } } void xml_strcpy_encode_entity(char *dest, const char *src) { *dest = 0; for(; *src; src++) { switch(*src) { case '<' : strcpy(dest, "<"); dest += 4; break; case '>' : strcpy(dest, ">"); dest += 4; break; case '&' : strcpy(dest, "&"); dest += 5; break; case '\'' : strcpy(dest, "'"); dest += 6; break; case '\"' : strcpy(dest, """); dest += 6; break; default : *dest = *src; *(++dest) = 0; break; } } } int xml_strncpy_encode_entity(char *dest, const char *src, int n) { int i=0; if(n < 1) { return(0); } *dest = 0; for(; *src; src++) { if((n - i) < 7) { break; } if(*src == '<') { strcpy(dest + i, "<"); i += 4; continue; } if(*src == '>') { strcpy(dest + i, ">"); i += 4; continue; } if(*src == '&') { strcpy(dest + i, "&"); i += 5; continue; } if(*src == '\'') { strcpy(dest + i, "'"); i += 6; continue; } if(*src == '\"') { strcpy(dest + i, """); i += 6; continue; } dest[i++] = *src; } dest[i] = 0; return(i); } void xml_strcpy_decode_entity(char *dest, const char *src) { int i, len, p=0; len = strlen(src); for(i=0; i= (n - 1)) { i++; break; } } return(i); } int xml_get_attribute_of_element(struct xml_handle *handle_p, const char *attr_name, char *str_buf, int content_len) { if(handle_p == NULL) return(1); while(handle_p->child_handle_p != NULL) { handle_p = handle_p->child_handle_p; } if(handle_p->attributes == NULL) return(1); if(strlen(attr_name) < 1) return(1); if(content_len < 1) return(1); if(xml_attribute(handle_p->attributes, attr_name, str_buf, content_len) < 1) { return(1); } return(0); } int xml_attribute(const char *data, const char *item, char *result, int result_len) { int i, j, data_len, item_len, quote=0; if(data == NULL) { return(-1); } data_len = strlen(data); item_len = strlen(item); if((data_len < 4) || (item_len >= (data_len - 4))) { return(-1); } for(i=0; i<(data_len - item_len); i++) { if(data[i] == '\"') { if(quote) { quote--; } else { quote++; } } if(quote) continue; if(!strncmp(data + i, item, item_len)) { i += item_len; if(i < (data_len - 3)) { if(!strncmp(data + i, "=\"", 2)) { i += 2; for(j=i; jfile = fopen(filename, "rb"); if(handle_p->file==NULL) { xml_close(handle_p); return(NULL); } handle_p->offset = next_tag(0, handle_p); if(handle_p->offset==-1) { xml_close(handle_p); return(NULL); } if(handle_p->tag_search_result==NULL) { xml_close(handle_p); return(NULL); } if(strlen(handle_p->tag_search_result) < 3) { xml_close(handle_p); return(NULL); } if((handle_p->tag_search_result[0] == '?') && (handle_p->tag_search_result[strlen(handle_p->tag_search_result) - 1] == '?')) { if(xml_attribute(handle_p->tag_search_result, "encoding", scratchpad, 512) < 0) { handle_p->encoding = 0; // attribute encoding not present } else { if((!strcmp(scratchpad, "ISO-8859-1")) || (!strcmp(scratchpad, "iso-8859-1"))) { handle_p->encoding = 1; } else if((!strcmp(scratchpad, "UTF-8")) || (!strcmp(scratchpad, "utf-8"))) { handle_p->encoding = 2; } else { handle_p->encoding = 99999; // unknown encoding } } } while((handle_p->tag_search_result[0]=='!') || (handle_p->tag_search_result[0]=='?')) { handle_p->offset = next_tag(handle_p->offset, handle_p); if(handle_p->offset==-1) { xml_close(handle_p); return(NULL); } if(handle_p->tag_search_result==NULL) { xml_close(handle_p); return(NULL); } } if(process_tag(handle_p->tag_search_result , handle_p)) { xml_close(handle_p); return(NULL); } return(handle_p); } struct xml_handle * xml_create_handle(const char *filename, char *rootname) { int len; struct xml_handle *handle_p; len = strlen(rootname); if(!len) return(NULL); handle_p = (struct xml_handle *)calloc(1, sizeof(struct xml_handle)); if(handle_p==NULL) return(NULL); handle_p->file = fopen(filename, "wb+"); if(handle_p->file==NULL) { free(handle_p); return(NULL); } fprintf(handle_p->file, "\n<%s>\n\n", rootname, rootname); handle_p->offset = (ftell(handle_p->file) - len) - 4; handle_p->elementname = (char *)calloc(1, len + 1); if(handle_p->elementname==NULL) { fclose(handle_p->file); free(handle_p); return(NULL); } strncpy(handle_p->elementname, rootname, len); handle_p->elementname[len] = 0; return(handle_p); } char * xml_get_content_of_element(struct xml_handle *handle_p) { int i, j, offset, len, deep=0, cdata=0; char *content; if(handle_p==NULL) return(NULL); while(handle_p->child_handle_p!=NULL) { handle_p = handle_p->child_handle_p; } if(handle_p->elementname==NULL) return(NULL); offset = handle_p->offset; len = strlen(handle_p->elementname); while(1) { offset = next_tag(offset, handle_p); if(offset == -1) { return(NULL); } if(handle_p->tag_search_result==NULL) { return(NULL); } if((handle_p->tag_search_result[0]=='!') || (handle_p->tag_search_result[0]=='?')) { continue; } if(handle_p->tag_search_result[0]=='/') { if(deep) deep--; else break; } else { deep++; } } offset -= (len + 3); if(offsetoffset) return(NULL); fseek(handle_p->file, handle_p->offset, SEEK_SET); content = (char *)calloc(1, offset - handle_p->offset + 1); if(content==NULL) { return(NULL); } if(offset>handle_p->offset) { if(fread(content, offset - handle_p->offset, 1, handle_p->file) != 1) { free(content); return(NULL); } } len = offset - handle_p->offset; content[len] = 0; if(len > 11) // cdata? { if(!(strncmp(content, "'; for(j=i+1; content[j-1]!=0; j++) { content[j] = content[j+3]; } } } if(i <= (len - 5)) { if(!strncmp(content + i + 1, "apos;", 5)) { content[i] = '\''; for(j=i+1; content[j-1]!=0; j++) { content[j] = content[j+5]; } } if(!strncmp(content + i + 1, "quot;", 5)) { content[i] = '\"'; for(j=i+1; content[j-1]!=0; j++) { content[j] = content[j+5]; } } } if(i <= (len - 4)) { if(!strncmp(content + i + 1, "amp;", 4)) { for(j=i+1; content[j-1]!=0; j++) { content[j] = content[j+4]; } } } } } } return(content); } int xml_goto_next_element_with_same_name(struct xml_handle *handle_p) { int len, offset, deep=0; if(handle_p==NULL) return(1); while(handle_p->child_handle_p!=NULL) { handle_p = handle_p->child_handle_p; } if(handle_p->elementname==NULL) return(1); len = strlen(handle_p->elementname); offset = handle_p->offset; while(1) { offset = next_tag(offset, handle_p); if(offset == -1) { return(1); } if(handle_p->tag_search_result==NULL) { return(1); } if((handle_p->tag_search_result[0]=='!') || (handle_p->tag_search_result[0]=='?')) { continue; } if(handle_p->tag_search_result[0]=='/') { if(deep) deep--; else break; } else { deep++; } } while(1) { offset = next_tag(offset, handle_p); if(offset == -1) { return(1); } if(handle_p->tag_search_result==NULL) { return(1); } if((handle_p->tag_search_result[0]=='!') || (handle_p->tag_search_result[0]=='?')) { continue; } if(handle_p->tag_search_result[0]=='/') { if(deep) deep--; else return(1); } else { if((int)strlen(handle_p->tag_search_result)>=len) { if((!strncmp(handle_p->tag_search_result, handle_p->elementname, len))&&(!deep)) { if(process_tag(handle_p->tag_search_result, handle_p)) { return(1); } handle_p->offset = offset; return(0); } else { deep++; } } else { deep++; } } } } int xml_goto_next_element_at_same_level(struct xml_handle *handle_p) { int offset, deep=0, ts_len; if(handle_p==NULL) return(1); while(handle_p->child_handle_p!=NULL) { handle_p = handle_p->child_handle_p; } offset = handle_p->offset; while(1) { offset = next_tag(offset, handle_p); if(offset == -1) { return(1); } if(handle_p->tag_search_result==NULL) { return(1); } if((handle_p->tag_search_result[0]=='!') || (handle_p->tag_search_result[0]=='?')) { continue; } if(handle_p->tag_search_result[0]=='/') { if(deep) deep--; else break; } else { ts_len = strlen(handle_p->tag_search_result); if(handle_p->tag_search_result[ts_len - 1]!='/') { deep++; } } } offset = next_tag(offset, handle_p); if(offset == -1) { return(1); } if(handle_p->tag_search_result==NULL) { return(1); } while((handle_p->tag_search_result[0]=='!') || (handle_p->tag_search_result[0]=='?')) { offset = next_tag(offset, handle_p); if(offset == -1) { return(1); } if(handle_p->tag_search_result==NULL) { return(1); } } if(handle_p->tag_search_result[0]=='/') { return(1); } if(process_tag(handle_p->tag_search_result, handle_p)) { return(1); } handle_p->offset = offset; return(0); } int xml_goto_nth_element_inside(struct xml_handle *handle_p, const char *name, int n) { int len, offset, deep=0, cnt=0, ts_len; struct xml_handle *new_handle_p; if(handle_p==NULL) return(1); while(handle_p->child_handle_p!=NULL) { handle_p = handle_p->child_handle_p; } len = strlen(name); offset = handle_p->offset; while(1) { while(1) { offset = next_tag(offset, handle_p); if(offset == -1) { return(1); } if(handle_p->tag_search_result==NULL) { return(1); } if((handle_p->tag_search_result[0]=='!') || (handle_p->tag_search_result[0]=='?')) { continue; } if(handle_p->tag_search_result[0]=='/') { if(deep) deep--; else return(1); } else { ts_len = strlen(handle_p->tag_search_result); if(handle_p->tag_search_result[ts_len - 1]!='/') { deep++; } break; } } if((int)strlen(handle_p->tag_search_result)>=len) { if(!strncmp(handle_p->tag_search_result, name, len)) { if((handle_p->tag_search_result[len]==' ')||(handle_p->tag_search_result[len]==0)) { if(cnt==n) { new_handle_p = (struct xml_handle *)calloc(1, sizeof(struct xml_handle)); if(new_handle_p==NULL) { return(1); } handle_p->child_handle_p = new_handle_p; new_handle_p->file = handle_p->file; new_handle_p->level = handle_p->level + 1; new_handle_p->offset = offset; new_handle_p->len = 0; new_handle_p->elementname = NULL; new_handle_p->attributes = NULL; new_handle_p->parent_handle_p = handle_p; new_handle_p->child_handle_p = NULL; new_handle_p->tag_search_result = NULL; new_handle_p->encoding = handle_p->encoding; if(process_tag(handle_p->tag_search_result, new_handle_p)) { return(1); } return(0); } cnt++; } } } } return(1); } int process_tag(const char *str, struct xml_handle *handle_p) { int len, i, p; if(handle_p==NULL) return(1); len = strlen(str); if(!len) return(1); if((str[0]==' ')||(str[0]=='>')) return(1); for(i=0; i')) break; } if(handle_p->elementname != NULL) free(handle_p->elementname); handle_p->elementname = (char *)calloc(1, i + 1); if(handle_p->elementname==NULL) return(1); strncpy(handle_p->elementname, str, i); handle_p->elementname[i] = 0; if(handle_p->attributes != NULL) free(handle_p->attributes); if(str[i]!=' ') return(0); i++; p = i; for(; i') break; } len = i - p; if(len < 2) return(0); handle_p->attributes = (char *)calloc(1, len + 1); if(handle_p->attributes==NULL) return(1); strncpy(handle_p->attributes, str + p, len); handle_p->attributes[len] = 0; return(0); } void xml_close(struct xml_handle *handle_p) /* delete everything and close the file */ { if(handle_p!=NULL) { xml_goto_root(handle_p); if(handle_p->file != NULL) fclose(handle_p->file); if(handle_p->elementname) free(handle_p->elementname); if(handle_p->attributes) free(handle_p->attributes); if(handle_p->tag_search_result) free(handle_p->tag_search_result); free(handle_p); handle_p = NULL; } } void xml_goto_root(struct xml_handle *handle_p) /* go to rootlevel and delete everything beneath */ { if(handle_p==NULL) return; while(handle_p->child_handle_p!=NULL) { handle_p = handle_p->child_handle_p; } while(handle_p->level!=0) { if(handle_p->elementname != NULL) free(handle_p->elementname); if(handle_p->attributes != NULL) free(handle_p->attributes); if(handle_p->tag_search_result != NULL) free(handle_p->tag_search_result); handle_p = handle_p->parent_handle_p; free(handle_p->child_handle_p); } handle_p->child_handle_p = NULL; } void xml_go_up(struct xml_handle *handle_p) /* go one level up and delete everything beneath */ { int level; if(handle_p==NULL) return; while(handle_p->child_handle_p!=NULL) { handle_p = handle_p->child_handle_p; } level = handle_p->level; if(level==0) return; level--; while(handle_p->level!=level) { if(handle_p->elementname != NULL) free(handle_p->elementname); if(handle_p->attributes != NULL) free(handle_p->attributes); if(handle_p->tag_search_result != NULL) free(handle_p->tag_search_result); handle_p = handle_p->parent_handle_p; free(handle_p->child_handle_p); } handle_p->child_handle_p = NULL; } int next_tag(int offset, struct xml_handle *handle_p) /* returns offset after '>' */ { int temp, fp1=0, fp2=0, tagstart=0, tag_char_cnt=0, comment=0, cdata=0; char circ_buf[16]; if(handle_p->tag_search_result!=NULL) { free(handle_p->tag_search_result); } handle_p->tag_search_result = NULL; fseek(handle_p->file, offset, SEEK_SET); while(1) { temp = fgetc(handle_p->file); if(temp==EOF) { return(-1); } if(tagstart) { circ_buf[tag_char_cnt % 16] = temp; tag_char_cnt++; if(tag_char_cnt == 3) { if(!strncmp(circ_buf, "!--", 3)) // start of comment { comment = 1; } } if(tag_char_cnt == 8) { if(!strncmp(circ_buf, "![CDATA[", 8)) // start of cdata { cdata = 1; } } } if(!comment) { if(!cdata) { if(temp=='<') { if(tagstart) { return(-1); } tagstart = 1; fp1 = ftell(handle_p->file); } if(temp=='>') { if(!tagstart) { return(-1); } offset = ftell(handle_p->file); fp2 = offset - 1; break; } } else // cdata { if((temp=='>') && (tag_char_cnt > 10)) { if((circ_buf[(tag_char_cnt - 2) % 16] == ']') && (circ_buf[(tag_char_cnt - 3) % 16] == ']')) { // end of cdata cdata = 0; tagstart = 0; fp1 = 0; fp2 = 0; tag_char_cnt = 0; } } } } else // comment { if((temp=='>') && (tag_char_cnt > 5)) { if((circ_buf[(tag_char_cnt - 2) % 16] == '-') && (circ_buf[(tag_char_cnt - 3) % 16] == '-')) { // end of comment comment = 0; tagstart = 0; fp1 = 0; fp2 = 0; tag_char_cnt = 0; } } } } if(!fp2) { return(-1); } fseek(handle_p->file, fp1, SEEK_SET); handle_p->tag_search_result = (char *)calloc(1, fp2 - fp1 + 1); if(handle_p->tag_search_result==NULL) { return(-1); } if(fread(handle_p->tag_search_result, fp2 - fp1, 1, handle_p->file) != 1) { free(handle_p->tag_search_result); handle_p->tag_search_result = NULL; return(-1); } handle_p->tag_search_result[fp2 - fp1] = 0; return(offset); } edfbrowser_153_source/PaxHeaders.2978/filter_dialog.cpp0000644000175000001440000000013212251654530021457 xustar000000000000000030 mtime=1386699096.477032522 30 atime=1386699096.477032522 30 ctime=1386699096.477032522 edfbrowser_153_source/filter_dialog.cpp0000644000175000001440000005557112251654530021225 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * The current version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ /* type: 0 : highpass 1 : lowpass 2 : notch 3 : bandpass 4 : bandstop model: 0 : Butterworth 1 : Chebyshev 2 : Bessel 3 : moving average 0 : resonator */ #include "filter_dialog.h" UI_FilterDialog::UI_FilterDialog(QWidget *w_parent) { int i; QListWidgetItem *item; arraysize = 400; last_order = 1; last_samples = 16; last_qfactor = 20; last_model = 0; last_ripple = -1.0; mainwindow = (UI_Mainwindow *)w_parent; filterdialog = new QDialog; filterdialog->setMinimumSize(QSize(620, 365)); filterdialog->setMaximumSize(QSize(620, 365)); filterdialog->setWindowTitle("Add a filter"); filterdialog->setModal(TRUE); filterdialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); typeboxlabel = new QLabel(filterdialog); typeboxlabel->setGeometry(QRect(20, 20, 120, 20)); typeboxlabel->setText("Type"); freqboxlabel = new QLabel(filterdialog); freqboxlabel->setGeometry(QRect(160, 20, 120, 20)); freqboxlabel->setText("Frequency"); freqbox2label = new QLabel(filterdialog); freqbox2label->setGeometry(QRect(300, 20, 120, 20)); freqbox2label->setText("Frequency 2"); freqbox2label->setVisible(FALSE); orderboxlabel = new QLabel(filterdialog); orderboxlabel->setGeometry(QRect(160, 80, 120, 20)); orderboxlabel->setText("Order"); modelboxlabel = new QLabel(filterdialog); modelboxlabel->setGeometry(QRect(20, 80, 120, 20)); modelboxlabel->setText("Model"); orderlabel = new QLabel(filterdialog); orderlabel->setGeometry(QRect(300, 80, 120, 20)); orderlabel->setText("Slope roll-off:"); ordervaluelabel = new QLabel(filterdialog); ordervaluelabel->setGeometry(QRect(300, 105, 120, 20)); ordervaluelabel->setText("6 dB / octave"); typebox = new QComboBox(filterdialog); typebox->setGeometry(QRect(20, 45, 120, 20)); typebox->addItem("Highpass"); typebox->addItem("Lowpass"); typebox->addItem("Notch"); typebox->addItem("Bandpass"); typebox->addItem("Bandstop"); freqbox = new QDoubleSpinBox(filterdialog); freqbox->setGeometry(QRect(160, 45, 120, 20)); freqbox->setDecimals(6); freqbox->setSuffix(" Hz"); freqbox->setMinimum(0.0001); freqbox->setMaximum(100000.0); freqbox->setValue(1.0); freq2box = new QDoubleSpinBox(filterdialog); freq2box->setGeometry(QRect(300, 45, 120, 20)); freq2box->setDecimals(6); freq2box->setSuffix(" Hz"); freq2box->setMinimum(0.0001); freq2box->setMaximum(100000.0); freq2box->setValue(2.0); freq2box->setVisible(FALSE); orderbox = new QSpinBox(filterdialog); orderbox->setGeometry(QRect(160, 105, 120, 20)); orderbox->setMinimum(1); orderbox->setMaximum(8); orderbox->setSingleStep(1); orderbox->setValue(1); modelbox = new QComboBox(filterdialog); modelbox->setGeometry(QRect(20, 105, 120, 20)); modelbox->addItem("Butterworth"); modelbox->addItem("Chebyshev"); modelbox->addItem("Bessel"); modelbox->addItem("Moving Average"); ripplebox = new QDoubleSpinBox(filterdialog); ripplebox->setGeometry(QRect(300, 105, 120, 20)); ripplebox->setDecimals(6); ripplebox->setSuffix(" dB"); ripplebox->setMinimum(0.1); ripplebox->setMaximum(6.0); ripplebox->setValue(1.0); ripplebox->setVisible(FALSE); listlabel = new QLabel(filterdialog); listlabel->setGeometry(QRect(440, 20, 100, 20)); listlabel->setText("Select signals:"); list = new QListWidget(filterdialog); list->setGeometry(QRect(440, 45, 160, 300)); list->setSelectionBehavior(QAbstractItemView::SelectRows); list->setSelectionMode(QAbstractItemView::ExtendedSelection); CancelButton = new QPushButton(filterdialog); CancelButton->setGeometry(QRect(300, 320, 100, 25)); CancelButton->setText("&Cancel"); ApplyButton = new QPushButton(filterdialog); ApplyButton->setGeometry(QRect(20, 320, 100, 25)); ApplyButton->setText("&Apply"); curve1 = new FilterCurve(filterdialog); curve1->setGeometry(QRect(20, 145, 400, 150)); curve1->setH_RasterSize(10); curve1->setV_RasterSize(14); for(i=0; isignalcomps; i++) { item = new QListWidgetItem; if(mainwindow->signalcomp[i]->alias[0] != 0) { item->setText(mainwindow->signalcomp[i]->alias); } else { item->setText(mainwindow->signalcomp[i]->signallabel); } item->setData(Qt::UserRole, QVariant(i)); list->addItem(item); } list->setCurrentRow(0); QObject::connect(ApplyButton, SIGNAL(clicked()), this, SLOT(ApplyButtonClicked())); QObject::connect(CancelButton, SIGNAL(clicked()), filterdialog, SLOT(close())); QObject::connect(freqbox, SIGNAL(valueChanged(double)), this, SLOT(frequencyboxvaluechanged(double))); QObject::connect(typebox, SIGNAL(currentIndexChanged(int)), this, SLOT(filtertypeboxvaluechanged(int))); QObject::connect(orderbox, SIGNAL(valueChanged(int)), this, SLOT(orderboxvaluechanged(int))); QObject::connect(modelbox, SIGNAL(currentIndexChanged(int)), this, SLOT(filtermodelboxvaluechanged(int))); QObject::connect(ripplebox, SIGNAL(valueChanged(double)), this, SLOT(rippleboxvaluechanged(double))); QObject::connect(freq2box, SIGNAL(valueChanged(double)), this, SLOT(freq2boxvaluechanged(double))); updatecurve(); filterdialog->exec(); } void UI_FilterDialog::updatecurve(void) { int i, type=0, rate=3200, order=1, model=0; double frequency=150.0, ripple=1.0, frequency2=200.0; char *err; FidFilter *ff; order = orderbox->value(); type = typebox->currentIndex(); model = modelbox->currentIndex(); if(model == 3) { for(i=0; idrawCurve(array, arraysize, 1.4, 0.0); return; } ripple = -(ripplebox->value()); if((type == 3) || (type == 4)) { frequency = frequency2 * (freqbox->value() / freq2box->value()); } spec_str_1[0] = 0; if(type == 0) { if(model == 0) { sprintf(spec_str_1, "HpBu%i/%f", order, frequency); } if(model == 1) { sprintf(spec_str_1, "HpCh%i/%f/%f", order, ripple, frequency); } if(model == 2) { sprintf(spec_str_1, "HpBe%i/%f", order, frequency); } } if(type == 1) { if(model == 0) { sprintf(spec_str_1, "LpBu%i/%f", order, frequency); } if(model == 1) { sprintf(spec_str_1, "LpCh%i/%f/%f", order, ripple, frequency); } if(model == 2) { sprintf(spec_str_1, "LpBe%i/%f", order, frequency); } } if(type == 2) { sprintf(spec_str_1, "BsRe/%i/%f", order, frequency); } if(type == 3) { if(model == 0) { sprintf(spec_str_1, "BpBu%i/%f-%f", order, frequency, frequency2); } if(model == 1) { sprintf(spec_str_1, "BpCh%i/%f/%f-%f", order, ripple, frequency, frequency2); } if(model == 2) { sprintf(spec_str_1, "BpBe%i/%f-%f", order, frequency, frequency2); } } if(type == 4) { if(model == 0) { sprintf(spec_str_1, "BsBu%i/%f-%f", order, frequency, frequency2); } if(model == 1) { sprintf(spec_str_1, "BsCh%i/%f/%f-%f", order, ripple, frequency, frequency2); } if(model == 2) { sprintf(spec_str_1, "BsBe%i/%f-%f", order, frequency, frequency2); } } strcpy(spec_str_2, spec_str_1); filter_spec = spec_str_2; err = fid_parse(rate, &filter_spec, &ff); if(err != NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", err); messagewindow.exec(); free(err); return; } for(i=0; idrawCurve(array, arraysize, 1.4, 0.0, array_pha, arraysize, 0.0, 1.0, frequency, frequency2); } else { curve1->drawCurve(array, arraysize, 1.4, 0.0, array_pha, arraysize, 0.0, 1.0, frequency); } free(ff); } void UI_FilterDialog::rippleboxvaluechanged(double value) { last_ripple = value; updatecurve(); } void UI_FilterDialog::filtermodelboxvaluechanged(int model) { int type; QObject::disconnect(orderbox, SIGNAL(valueChanged(int)), this, SLOT(orderboxvaluechanged(int))); QObject::disconnect(modelbox, SIGNAL(currentIndexChanged(int)), this, SLOT(filtermodelboxvaluechanged(int))); type = typebox->currentIndex(); last_model = model; freqboxlabel->setText("Frequency"); freqbox->setVisible(TRUE); if(type != 2) { orderboxlabel->setText("Order"); if((type == 3) || (type == 4)) { orderbox->setMaximum(16); } else { orderbox->setMaximum(8); } orderbox->setSingleStep(1); orderbox->setMinimum(1); orderbox->setValue(last_order); if(model == 0) { ripplebox->setVisible(FALSE); ordervaluelabel->setVisible(TRUE); orderlabel->setText("Slope roll-off:"); ordervaluelabel->setText(QString::number(6 * orderbox->value(), 'f', 0).append(" dB / octave")); } if(model == 1) { orderlabel->setText("passband ripple"); ordervaluelabel->setVisible(FALSE); ripplebox->setVisible(TRUE); } if(model == 2) { ripplebox->setVisible(FALSE); ordervaluelabel->setVisible(TRUE); orderlabel->setText(""); ordervaluelabel->setText(""); } if(model == 3) { orderlabel->setText(""); ordervaluelabel->setText(""); freqboxlabel->setText(""); freqbox2label->setText(""); freqbox->setVisible(FALSE); ripplebox->setVisible(FALSE); ordervaluelabel->setVisible(FALSE); orderlabel->setText(""); ordervaluelabel->setText(""); orderboxlabel->setText("Samples"); orderbox->setMaximum(10000); orderbox->setSingleStep(1); orderbox->setMinimum(2); orderbox->setValue(last_samples); } } updatecurve(); QObject::connect(orderbox, SIGNAL(valueChanged(int)), this, SLOT(orderboxvaluechanged(int))); QObject::connect(modelbox, SIGNAL(currentIndexChanged(int)), this, SLOT(filtermodelboxvaluechanged(int))); } void UI_FilterDialog::orderboxvaluechanged(int order) { int type, model; char str[256]; type = typebox->currentIndex(); model = modelbox->currentIndex(); if(type == 2) { sprintf(str,"%f Hz", freqbox->value() / orderbox->value()); remove_trailing_zeros(str); ordervaluelabel->setText(str); last_qfactor = order; } else { if((type == 3) || (type == 4)) { last_order = order / 2; } else { if(model == 3) { last_samples = order; } else { last_order = order; } } if(model == 0) { orderlabel->setText("Slope roll-off:"); ordervaluelabel->setText(QString::number(6 * last_order, 'f', 0).append(" dB / octave")); } if(model == 1) { orderlabel->setText("passband ripple"); ordervaluelabel->setText("1 dB"); } if(model == 2) { orderlabel->setText(""); ordervaluelabel->setText(""); } if(model == 3) { orderlabel->setText(""); ordervaluelabel->setText(""); } } updatecurve(); } void UI_FilterDialog::filtertypeboxvaluechanged(int type) { char str[256]; QObject::disconnect(orderbox, SIGNAL(valueChanged(int)), this, SLOT(orderboxvaluechanged(int))); QObject::disconnect(modelbox, SIGNAL(currentIndexChanged(int)), this, SLOT(filtermodelboxvaluechanged(int))); if(type == 2) { ripplebox->setVisible(FALSE); ordervaluelabel->setVisible(TRUE); orderboxlabel->setText("Notch Q-factor"); orderbox->setMaximum(100); orderbox->setSingleStep(1); orderbox->setMinimum(3); orderbox->setValue(last_qfactor); orderlabel->setText("-3 dB bandwidth:"); sprintf(str,"%f Hz", freqbox->value() / orderbox->value()); remove_trailing_zeros(str); ordervaluelabel->setText(str); modelbox->clear(); modelbox->addItem("Resonator"); } else { orderboxlabel->setText("Order"); if((type == 3) || (type == 4)) { orderbox->setMaximum(16); orderbox->setSingleStep(2); orderbox->setMinimum(2); orderbox->setValue(last_order * 2); } else { orderbox->setMaximum(8); orderbox->setSingleStep(1); orderbox->setMinimum(1); orderbox->setValue(last_order); } if(last_model == 3) { if(type < 2) { ripplebox->setVisible(FALSE); ordervaluelabel->setVisible(FALSE); orderlabel->setText(""); ordervaluelabel->setText(""); orderboxlabel->setText("Samples"); orderbox->setMaximum(10000); orderbox->setSingleStep(1); orderbox->setMinimum(2); orderbox->setValue(last_samples); } else { last_model = 0; } } if(last_model == 0) { ripplebox->setVisible(FALSE); ordervaluelabel->setVisible(TRUE); orderlabel->setText("Slope roll-off:"); ordervaluelabel->setText(QString::number(6 * last_order, 'f', 0).append(" dB / octave")); } if(last_model == 1) { ordervaluelabel->setVisible(FALSE); ripplebox->setVisible(TRUE); orderlabel->setText("passband ripple"); ordervaluelabel->setText("1 dB"); } if(last_model == 2) { ripplebox->setVisible(FALSE); ordervaluelabel->setVisible(TRUE); orderlabel->setText(""); ordervaluelabel->setText(""); } modelbox->clear(); modelbox->addItem("Butterworth"); modelbox->addItem("Chebyshev"); modelbox->addItem("Bessel"); if(type < 2) { modelbox->addItem("Moving Average"); } modelbox->setCurrentIndex(last_model); } if((type == 3) || (type == 4)) { freqboxlabel->setText("Frequency 1"); freqbox2label->setText("Frequency 2"); freqbox2label->setVisible(TRUE); freq2box->setVisible(TRUE); } else { freqbox2label->setVisible(FALSE); freq2box->setVisible(FALSE); if(last_model == 3) { orderlabel->setText(""); ordervaluelabel->setText(""); freqboxlabel->setText(""); freqbox2label->setText(""); } else { freqboxlabel->setText("Frequency"); freqbox2label->setText(""); } } QObject::connect(orderbox, SIGNAL(valueChanged(int)), this, SLOT(orderboxvaluechanged(int))); QObject::connect(modelbox, SIGNAL(currentIndexChanged(int)), this, SLOT(filtermodelboxvaluechanged(int))); updatecurve(); } void UI_FilterDialog::frequencyboxvaluechanged(double value) { char str[256]; if(freq2box->value() < (value * 1.12)) { freq2box->setValue(value * 1.12); } if(typebox->currentIndex() == 2) { sprintf(str,"%f Hz", freqbox->value() / orderbox->value()); remove_trailing_zeros(str); ordervaluelabel->setText(str); } updatecurve(); } void UI_FilterDialog::freq2boxvaluechanged(double value) { QObject::disconnect(freqbox, SIGNAL(valueChanged(double)), this, SLOT(frequencyboxvaluechanged(double))); if(freqbox->value() > (value * 0.9)) { freqbox->setValue(value * 0.9); } QObject::connect(freqbox, SIGNAL(valueChanged(double)), this, SLOT(frequencyboxvaluechanged(double))); updatecurve(); } void UI_FilterDialog::ApplyButtonClicked() { int i, s, n, type, model, order; double frequency, frequency2, ripple; char *err; QListWidgetItem *item; QList selectedlist; selectedlist = list->selectedItems(); n = selectedlist.size(); if(!n) { filterdialog->close(); return; } frequency = freqbox->value(); frequency2 = freq2box->value(); order = orderbox->value(); type = typebox->currentIndex(); model = modelbox->currentIndex(); ripple = -(ripplebox->value()); for(i=0; idata(Qt::UserRole).toInt(); if((mainwindow->signalcomp[s]->filter_cnt + mainwindow->signalcomp[s]->fidfilter_cnt) > MAXFILTERS - 1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "The maximum amount of filters per signal has been reached.\n" "Remove some filters first."); messagewindow.exec(); return; } } if(model < 3) { for(i=0; irow(item); if(type < 3) { if(frequency >= ((mainwindow->signalcomp[s]->edfhdr->edfparam[mainwindow->signalcomp[s]->edfsignal[0]].smp_per_record / mainwindow->signalcomp[s]->edfhdr->data_record_duration) / 2.0)) { UI_Messagewindow errormessage("Error", "The frequency of the filter(s) must be less than: samplerate / 2"); return; } } else { if(frequency2 >= ((mainwindow->signalcomp[s]->edfhdr->edfparam[mainwindow->signalcomp[s]->edfsignal[0]].smp_per_record / mainwindow->signalcomp[s]->edfhdr->data_record_duration) / 2.0)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "The frequency of the filter(s) must be less than: samplerate / 2"); messagewindow.exec(); return; } } } spec_str_1[0] = 0; if(type == 0) { if(model == 0) { sprintf(spec_str_1, "HpBu%i/%f", order, frequency); } if(model == 1) { sprintf(spec_str_1, "HpCh%i/%f/%f", order, ripple, frequency); } if(model == 2) { sprintf(spec_str_1, "HpBe%i/%f", order, frequency); } } if(type == 1) { if(model == 0) { sprintf(spec_str_1, "LpBu%i/%f", order, frequency); } if(model == 1) { sprintf(spec_str_1, "LpCh%i/%f/%f", order, ripple, frequency); } if(model == 2) { sprintf(spec_str_1, "LpBe%i/%f", order, frequency); } } if(type == 2) { sprintf(spec_str_1, "BsRe/%i/%f", order, frequency); } if(type == 3) { if(model == 0) { sprintf(spec_str_1, "BpBu%i/%f-%f", order, frequency, frequency2); } if(model == 1) { sprintf(spec_str_1, "BpCh%i/%f/%f-%f", order, ripple, frequency, frequency2); } if(model == 2) { sprintf(spec_str_1, "BpBe%i/%f-%f", order, frequency, frequency2); } } if(type == 4) { if(model == 0) { sprintf(spec_str_1, "BsBu%i/%f-%f", order, frequency, frequency2); } if(model == 1) { sprintf(spec_str_1, "BsCh%i/%f/%f-%f", order, ripple, frequency, frequency2); } if(model == 2) { sprintf(spec_str_1, "BsBe%i/%f-%f", order, frequency, frequency2); } } for(i=0; irow(item); strcpy(spec_str_2, spec_str_1); filter_spec = spec_str_2; err = fid_parse(((double)(mainwindow->signalcomp[s]->edfhdr->edfparam[mainwindow->signalcomp[s]->edfsignal[0]].smp_per_record)) / mainwindow->signalcomp[s]->edfhdr->data_record_duration, &filter_spec, &mainwindow->signalcomp[s]->fidfilter[mainwindow->signalcomp[s]->fidfilter_cnt]); if(err != NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", err); messagewindow.exec(); free(err); filterdialog->close(); return; } mainwindow->signalcomp[s]->fid_run[mainwindow->signalcomp[s]->fidfilter_cnt] = fid_run_new(mainwindow->signalcomp[s]->fidfilter[mainwindow->signalcomp[s]->fidfilter_cnt], &mainwindow->signalcomp[s]->fidfuncp[mainwindow->signalcomp[s]->fidfilter_cnt]); mainwindow->signalcomp[s]->fidbuf[mainwindow->signalcomp[s]->fidfilter_cnt] = fid_run_newbuf(mainwindow->signalcomp[s]->fid_run[mainwindow->signalcomp[s]->fidfilter_cnt]); mainwindow->signalcomp[s]->fidbuf2[mainwindow->signalcomp[s]->fidfilter_cnt] = fid_run_newbuf(mainwindow->signalcomp[s]->fid_run[mainwindow->signalcomp[s]->fidfilter_cnt]); mainwindow->signalcomp[s]->fidfilter_freq[mainwindow->signalcomp[s]->fidfilter_cnt] = frequency; mainwindow->signalcomp[s]->fidfilter_freq2[mainwindow->signalcomp[s]->fidfilter_cnt] = frequency2; mainwindow->signalcomp[s]->fidfilter_ripple[mainwindow->signalcomp[s]->fidfilter_cnt] = ripple; mainwindow->signalcomp[s]->fidfilter_order[mainwindow->signalcomp[s]->fidfilter_cnt] = order; mainwindow->signalcomp[s]->fidfilter_model[mainwindow->signalcomp[s]->fidfilter_cnt] = model; mainwindow->signalcomp[s]->fidfilter_type[mainwindow->signalcomp[s]->fidfilter_cnt] = type; mainwindow->signalcomp[s]->fidfilter_setup[mainwindow->signalcomp[s]->fidfilter_cnt] = 1; mainwindow->signalcomp[s]->fidfilter_cnt++; } } if(model == 3) { for(i=0; irow(item); mainwindow->signalcomp[s]->ravg_filter[mainwindow->signalcomp[s]->ravg_filter_cnt] = create_ravg_filter(type, order); if(mainwindow->signalcomp[s]->ravg_filter[mainwindow->signalcomp[s]->ravg_filter_cnt] == NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while creating a moving average filter."); messagewindow.exec(); filterdialog->close(); return; } mainwindow->signalcomp[s]->ravg_filter_type[mainwindow->signalcomp[s]->ravg_filter_cnt] = type; mainwindow->signalcomp[s]->ravg_filter_size[mainwindow->signalcomp[s]->ravg_filter_cnt] = order; mainwindow->signalcomp[s]->ravg_filter_setup[mainwindow->signalcomp[s]->ravg_filter_cnt] = 1; mainwindow->signalcomp[s]->ravg_filter_cnt++; } } filterdialog->close(); mainwindow->setup_viewbuf(); } edfbrowser_153_source/PaxHeaders.2978/edit_predefined_mtg.h0000644000175000001440000000013212251654530022301 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/edit_predefined_mtg.h0000644000175000001440000000413512251654530022035 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef EDITPREDEFINEDMTGFORM1_H #define EDITPREDEFINEDMTGFORM1_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "mainwindow.h" #include "popup_messagewindow.h" class UI_Mainwindow; class UI_edit_predefined_mtg_window : public QObject { Q_OBJECT public: UI_edit_predefined_mtg_window(QWidget *parent); UI_Mainwindow *mainwindow; private: QDialog *edit_predefined_mtg_Dialog, *dialog; QListWidget *mtg_path_list; QPushButton *CloseButton, *button1, *button2, *button3; QListWidgetItem *listItem; int row; private slots: void rowClicked(QListWidgetItem *); void adEntry(); void removeEntry(); }; #endif edfbrowser_153_source/PaxHeaders.2978/popup_messagewindow.cpp0000644000175000001440000000013212251654530022752 xustar000000000000000030 mtime=1386699096.478032517 30 atime=1386699096.478032517 30 ctime=1386699096.478032517 edfbrowser_153_source/popup_messagewindow.cpp0000644000175000001440000000520012251654530022500 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "popup_messagewindow.h" UI_Messagewindow::UI_Messagewindow(const char *title, const char *str, const char *buttontxt, int timeout) { int i, len, max=0, labelwidth = 0, labelheight = 20; len = strlen(str); for(i=0; ilabelwidth) labelwidth = max; max = 0; } else { max++; } } if(max>labelwidth) labelwidth = max; labelwidth *= 6; labelwidth += 10; if(labelwidth<100) labelwidth = 100; MessageDialog = new QDialog; MessageDialog->setMinimumSize(QSize(labelwidth + 40, labelheight + 85)); MessageDialog->setMaximumSize(QSize(labelwidth + 40, labelheight + 85)); MessageDialog->setWindowTitle(title); MessageDialog->setModal(TRUE); MessageDialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); Label1 = new QLabel(MessageDialog); Label1->setGeometry(QRect(20, 20, labelwidth, labelheight)); Label1->setAlignment(Qt::AlignLeft | Qt::AlignTop); Label1->setText(str); pushButton1 = new QPushButton(MessageDialog); pushButton1->setGeometry(QRect(labelwidth - 80, labelheight + 40, 100, 25)); if(buttontxt == NULL) { pushButton1->setText("&Close"); } else { pushButton1->setText(buttontxt); } if(timeout > 100) { QTimer::singleShot(timeout, MessageDialog, SLOT(close())); } QObject::connect(pushButton1, SIGNAL(clicked()), MessageDialog, SLOT(close())); MessageDialog->exec(); } edfbrowser_153_source/PaxHeaders.2978/bdf_triggers.h0000644000175000001440000000013212251654530020761 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/bdf_triggers.h0000644000175000001440000000310112251654530020505 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef BDF_TRIGGERS_H #define BDF_TRIGGERS_H #include #include #include #include #include #include #include #include "global.h" #include "edf_annot_list.h" class BDF_triggers { public: int get_triggers(struct edfhdrblock *, struct annotationblock **); private: struct edfhdrblock *edfhdr; }; #endif // BDF_TRIGGERS_H edfbrowser_153_source/PaxHeaders.2978/bdf2edf.cpp0000644000175000001440000000013212251654530020147 xustar000000000000000030 mtime=1386699096.477032522 30 atime=1386699096.477032522 30 ctime=1386699096.477032522 edfbrowser_153_source/bdf2edf.cpp0000644000175000001440000004724712251654530017716 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "bdf2edf.h" #if defined(__APPLE__) || defined(__MACH__) || defined(__APPLE_CC__) #define fopeno fopen #else #define fseeko fseeko64 #define ftello ftello64 #define fopeno fopen64 #endif UI_BDF2EDFwindow::UI_BDF2EDFwindow(QWidget *w_parent) { mainwindow = (UI_Mainwindow *)w_parent; recent_opendir = mainwindow->recent_opendir; recent_savedir = mainwindow->recent_savedir; myobjectDialog = new QDialog; myobjectDialog->setMinimumSize(QSize(600, 526)); myobjectDialog->setMaximumSize(QSize(600, 526)); myobjectDialog->setWindowTitle("BDF+ to EDF+ converter"); myobjectDialog->setModal(TRUE); myobjectDialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); label1 = new QLabel(myobjectDialog); label1->setGeometry(20, 20, 560, 26); label2 = new QLabel(myobjectDialog); label2->setGeometry(440, 196, 100, 26); label2->setText("High-pass filter"); label3 = new QLabel(myobjectDialog); label3->setGeometry(440, 300, 100, 26); label3->setText("Divider"); SignalsTablewidget = new QTableWidget(myobjectDialog); SignalsTablewidget->setGeometry(20, 66, 400, 380); SignalsTablewidget->setSelectionMode(QAbstractItemView::NoSelection); SignalsTablewidget->setColumnCount(3); SignalsTablewidget->setColumnWidth(0, 140); SignalsTablewidget->setColumnWidth(1, 100); SignalsTablewidget->setColumnWidth(2, 100); QStringList horizontallabels; horizontallabels += "Label"; horizontallabels += "HighPassFilter"; horizontallabels += "Divider"; SignalsTablewidget->setHorizontalHeaderLabels(horizontallabels); spinBox1 = new QDoubleSpinBox(myobjectDialog); spinBox1->setGeometry(440, 232, 100, 26); spinBox1->setDecimals(3); spinBox1->setSuffix(" Hz"); spinBox1->setRange(0.001, 100.0); spinBox1->setValue(0.1); spinBox2 = new QDoubleSpinBox(myobjectDialog); spinBox2->setGeometry(440, 336, 100, 26); spinBox2->setDecimals(3); spinBox2->setRange(1.0, 256.0); spinBox2->setValue(1.0); pushButton1 = new QPushButton(myobjectDialog); pushButton1->setGeometry(QRect(20, 476, 100, 26)); pushButton1->setText("Select File"); pushButton2 = new QPushButton(myobjectDialog); pushButton2->setGeometry(QRect(480, 476, 100, 26)); pushButton2->setText("Close"); pushButton3 = new QPushButton(myobjectDialog); pushButton3->setGeometry(QRect(200, 476, 100, 26)); pushButton3->setText("Convert"); pushButton3->setEnabled(FALSE); pushButton4 = new QPushButton(myobjectDialog); pushButton4->setGeometry(QRect(440, 66, 140, 26)); pushButton4->setText("Select all signals"); pushButton4->setEnabled(FALSE); pushButton5 = new QPushButton(myobjectDialog); pushButton5->setGeometry(QRect(440, 118, 140, 26)); pushButton5->setText("Deselect all signals"); pushButton5->setEnabled(FALSE); QObject::connect(pushButton1, SIGNAL(clicked()), this, SLOT(SelectFileButton())); QObject::connect(pushButton2, SIGNAL(clicked()), myobjectDialog, SLOT(close())); QObject::connect(pushButton3, SIGNAL(clicked()), this, SLOT(StartConversion())); QObject::connect(pushButton4, SIGNAL(clicked()), this, SLOT(Select_all_signals())); QObject::connect(pushButton5, SIGNAL(clicked()), this, SLOT(Deselect_all_signals())); QObject::connect(spinBox1, SIGNAL(valueChanged(double)), this, SLOT(spinbox1_changed(double))); QObject::connect(spinBox2, SIGNAL(valueChanged(double)), this, SLOT(spinbox2_changed(double))); QObject::connect(myobjectDialog, SIGNAL(destroyed()), this, SLOT(free_edfheader())); edfhdr = NULL; inputfile = NULL; outputfile = NULL; inputpath[0] = 0; myobjectDialog->exec(); } void UI_BDF2EDFwindow::free_edfheader() { if(edfhdr != NULL) { free(edfhdr->edfparam); free(edfhdr); edfhdr = NULL; } } void UI_BDF2EDFwindow::Select_all_signals() { int i; if(edfhdr==NULL) { return; } for(i=0; iedfsignals; i++) { if(!edfhdr->edfparam[i].annotation) { ((QCheckBox *)(SignalsTablewidget->cellWidget(i, 0)))->setCheckState(Qt::Checked); } } } void UI_BDF2EDFwindow::Deselect_all_signals() { int i; if(edfhdr==NULL) { return; } for(i=0; iedfsignals; i++) { if(!edfhdr->edfparam[i].annotation) { ((QCheckBox *)(SignalsTablewidget->cellWidget(i, 0)))->setCheckState(Qt::Unchecked); } } } void UI_BDF2EDFwindow::spinbox1_changed(double value) { int i; if(edfhdr==NULL) { return; } for(i=0; iedfsignals; i++) { if(!edfhdr->edfparam[i].annotation) { ((QDoubleSpinBox *)(SignalsTablewidget->cellWidget(i, 1)))->setValue(value); } } } void UI_BDF2EDFwindow::spinbox2_changed(double value) { int i; if(edfhdr==NULL) { return; } for(i=0; iedfsignals; i++) { if(!edfhdr->edfparam[i].annotation) { ((QDoubleSpinBox *)(SignalsTablewidget->cellWidget(i, 2)))->setValue(value); } } } void UI_BDF2EDFwindow::SelectFileButton() { int i; char txt_string[2048]; if(edfhdr!=NULL) { label1->setText(""); SignalsTablewidget->setRowCount(0); free_edfheader(); inputfile = NULL; outputfile = NULL; inputpath[0] = 0; pushButton3->setEnabled(FALSE); pushButton4->setEnabled(FALSE); pushButton5->setEnabled(FALSE); } 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); inputfile = fopeno(inputpath, "rb"); if(inputfile==NULL) { snprintf(txt_string, 2048, "Can not open file %s for reading.", inputpath); QMessageBox messagewindow(QMessageBox::Critical, "Error", QString::fromLocal8Bit(txt_string)); messagewindow.exec(); return; } /***************** check if the file is valid ******************************/ EDFfileCheck EDFfilechecker; edfhdr = EDFfilechecker.check_edf_file(inputfile, txt_string); if(edfhdr==NULL) { fclose(inputfile); QMessageBox messagewindow(QMessageBox::Critical, "Error", txt_string); messagewindow.exec(); return; } if(!edfhdr->bdf) { fclose(inputfile); QMessageBox messagewindow(QMessageBox::Critical, "Error", "File is not a BDF file."); messagewindow.exec(); free_edfheader(); return; } /***************** load signalproperties ******************************/ label1->setText(QString::fromLocal8Bit(inputpath)); SignalsTablewidget->setRowCount(edfhdr->edfsignals); for(i=0; iedfsignals; i++) { SignalsTablewidget->setRowHeight(i, 20); SignalsTablewidget->setCellWidget(i, 0, new QCheckBox(edfhdr->edfparam[i].label)); ((QCheckBox *)(SignalsTablewidget->cellWidget(i, 0)))->setTristate(FALSE); ((QCheckBox *)(SignalsTablewidget->cellWidget(i, 0)))->setCheckState(Qt::Checked); if(!edfhdr->edfparam[i].annotation) { SignalsTablewidget->setCellWidget(i, 1, new QDoubleSpinBox); ((QDoubleSpinBox *)(SignalsTablewidget->cellWidget(i, 1)))->setDecimals(3); ((QDoubleSpinBox *)(SignalsTablewidget->cellWidget(i, 1)))->setSuffix(" Hz"); ((QDoubleSpinBox *)(SignalsTablewidget->cellWidget(i, 1)))->setRange(0.001, 100.0); ((QDoubleSpinBox *)(SignalsTablewidget->cellWidget(i, 1)))->setValue(spinBox1->value()); SignalsTablewidget->setCellWidget(i, 2, new QDoubleSpinBox); ((QDoubleSpinBox *)(SignalsTablewidget->cellWidget(i, 2)))->setDecimals(3); ((QDoubleSpinBox *)(SignalsTablewidget->cellWidget(i, 2)))->setRange(1.0, 256.0); ((QDoubleSpinBox *)(SignalsTablewidget->cellWidget(i, 2)))->setValue(spinBox2->value()); } else { ((QCheckBox *)(SignalsTablewidget->cellWidget(i, 0)))->setEnabled(FALSE); } } pushButton3->setEnabled(TRUE); pushButton4->setEnabled(TRUE); pushButton5->setEnabled(TRUE); } void UI_BDF2EDFwindow::StartConversion() { int i, j, k, datrecs, new_edfsignals, datarecords, len, progress_steps; char *readbuf, scratchpad[256]; union { unsigned int one; signed int one_signed; unsigned short two[2]; signed short two_signed[2]; unsigned char four[4]; } var; union { signed short one_short; unsigned char two_bytes[2]; } var2; pushButton3->setEnabled(FALSE); pushButton4->setEnabled(FALSE); pushButton5->setEnabled(FALSE); if(edfhdr==NULL) { return; } if(edfhdr->edfsignals>MAXSIGNALS) { return; } new_edfsignals = 0; for(i=0; iedfsignals; i++) { if(!edfhdr->edfparam[i].annotation) { if(((QCheckBox *)(SignalsTablewidget->cellWidget(i, 0)))->checkState()==Qt::Checked) { signalslist[new_edfsignals] = i; annotlist[new_edfsignals] = 0; filterlist[new_edfsignals] = create_filter(0, ((QDoubleSpinBox *)(SignalsTablewidget->cellWidget(i, 1)))->value(), 1.0 / (edfhdr->data_record_duration / edfhdr->edfparam[i].smp_per_record)); dividerlist[new_edfsignals] = ((QDoubleSpinBox *)(SignalsTablewidget->cellWidget(i, 2)))->value(); new_edfsignals++; } } else { signalslist[new_edfsignals] = i; annotlist[new_edfsignals] = 1; filterlist[new_edfsignals] = create_filter(0, 0.01, 1.0 / (edfhdr->data_record_duration / edfhdr->edfparam[i].smp_per_record)); dividerlist[new_edfsignals] = 1.0; new_edfsignals++; } } datarecords = edfhdr->datarecords; QProgressDialog progress("Converting...", "Abort", 0, datarecords, myobjectDialog); progress.setWindowModality(Qt::WindowModal); progress.setMinimumDuration(200); if(!new_edfsignals) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "You must select at least one signal."); messagewindow.exec(); goto END_1; } readbuf = (char *)malloc(edfhdr->recordsize); if(readbuf==NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Malloc error, (readbuf)."); messagewindow.exec(); goto END_2; } /////////////////////////// write header //////////////////////////////////////// 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); strcat(outputpath, ".edf"); strcpy(outputpath, QFileDialog::getSaveFileName(0, "Select outputfile", QString::fromLocal8Bit(outputpath), "EDF files (*.edf *.EDF)").toLocal8Bit().data()); if(!strcmp(outputpath, "")) { goto END_2; } get_directory_from_path(recent_savedir, outputpath, MAX_PATH_LENGTH); if(mainwindow->file_is_opened(outputpath)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Error, selected file is in use."); messagewindow.exec(); goto END_2; } outputfile = fopeno(outputpath, "wb"); if(outputfile==NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not open outputfile for writing."); messagewindow.exec(); goto END_2; } fprintf(outputfile, "0 "); fseeko(inputfile, 8LL, SEEK_SET); if(fread(scratchpad, 176, 1, inputfile)!=1) { showpopupmessage("Error", "Read error (1)."); QMessageBox messagewindow(QMessageBox::Critical, "Error", "Read error (1)."); messagewindow.exec(); goto END_3; } if(fwrite(scratchpad, 176, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Write error (1)."); messagewindow.exec(); goto END_3; } fprintf(outputfile, "%-8i", new_edfsignals * 256 + 256); if(edfhdr->bdfplus) { if(edfhdr->discontinuous) { fprintf(outputfile, "EDF+D"); } else { fprintf(outputfile, "EDF+C"); } for(i=0; i<39; i++) { fputc(' ', outputfile); } } else { 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); fprintf(outputfile, "%-4i", new_edfsignals); for(i=0; iedfparam[signalslist[i]].label); } } for(i=0; iedfparam[signalslist[i]].transducer); } for(i=0; iedfparam[signalslist[i]].physdimension); } for(i=0; iedfparam[signalslist[i]].bitvalue * -32768.0 * dividerlist[i]); convert_trailing_zeros_to_spaces(scratchpad); if(scratchpad[7]=='.') { scratchpad[7] = ' '; } scratchpad[8] = 0; fprintf(outputfile, "%s", scratchpad); } } for(i=0; iedfparam[signalslist[i]].bitvalue * 32767.0 * dividerlist[i]); convert_trailing_zeros_to_spaces(scratchpad); if(scratchpad[7]=='.') { scratchpad[7] = ' '; } scratchpad[8] = 0; fprintf(outputfile, "%s", scratchpad); } } for(i=0; icellWidget(signalslist[i], 1)))->value()); remove_trailing_zeros(scratchpad); strcat(scratchpad, "Hz "); strcat(scratchpad, edfhdr->edfparam[signalslist[i]].prefilter); for(j=strlen(scratchpad); j<200; j++) { scratchpad[j] = ' '; } scratchpad[200] = 0; for(j=0; j<80; j++) { if(!strncmp(scratchpad + j, "No filtering", 12)) { for(k=j; k<(j+12); k++) { scratchpad[k] = ' '; } } } for(j=0; j<80; j++) { if(!strncmp(scratchpad + j, "None", 4)) { for(k=j; k<(j+4); k++) { scratchpad[k] = ' '; } } } for(j=0; j<80; j++) { if(!strncmp(scratchpad + j, "HP: DC;", 7)) { for(k=j; k<(j+7); k++) { scratchpad[k] = ' '; } } } scratchpad[80] = 0; fprintf(outputfile, "%s", scratchpad); } } for(i=0; iedfparam[signalslist[i]].smp_per_record % 2) { fprintf(outputfile, "%-8i", ((edfhdr->edfparam[signalslist[i]].smp_per_record * 15) / 10) + 1); } else { fprintf(outputfile, "%-8i", (edfhdr->edfparam[signalslist[i]].smp_per_record * 15) / 10); } } else { fprintf(outputfile, "%-8i", edfhdr->edfparam[signalslist[i]].smp_per_record); } } for(i=0; i<(new_edfsignals * 32); i++) { fputc(' ', outputfile); } ///////////////////////////// start conversion ////////////////////////////////////// progress_steps = datarecords / 100; if(progress_steps < 1) { progress_steps = 1; } fseeko(inputfile, (long long)(edfhdr->hdrsize), SEEK_SET); for(datrecs=0; datrecsprocessEvents(); if(progress.wasCanceled() == TRUE) { goto END_3; } } if(fread(readbuf, edfhdr->recordsize, 1, inputfile) != 1) { progress.reset(); showpopupmessage("Error", "Read error (2)."); goto END_3; } for(i=0; iedfparam[signalslist[i]].buf_offset, edfhdr->edfparam[signalslist[i]].smp_per_record * 3, 1, outputfile)!=1) { progress.reset(); showpopupmessage("Error", "Write error (2)."); goto END_3; } if(edfhdr->edfparam[signalslist[i]].smp_per_record % 2) { if(fputc(0, outputfile)==EOF) { progress.reset(); showpopupmessage("Error", "Write error (3)."); goto END_3; } } } else { for(j=0; jedfparam[signalslist[i]].smp_per_record; j++) { var.two[0] = *((unsigned short *)(readbuf + edfhdr->edfparam[signalslist[i]].buf_offset + (j * 3))); var.four[2] = *((unsigned char *)(readbuf + edfhdr->edfparam[signalslist[i]].buf_offset + (j * 3) + 2)); if(var.four[2]&0x80) { var.four[3] = 0xff; } else { var.four[3] = 0x00; } var.one_signed += edfhdr->edfparam[signalslist[i]].offset; var.one_signed = first_order_filter(var.one_signed, filterlist[i]); var.one_signed /= dividerlist[i]; if(var.one_signed>32767) var.one_signed = 32767; if(var.one_signed<-32768) var.one_signed = -32768; var2.one_short = var.one_signed; fputc(var2.two_bytes[0], outputfile); if(fputc(var2.two_bytes[1], outputfile)==EOF) { progress.reset(); showpopupmessage("Error", "Write error (4)."); goto END_3; } } } } } progress.reset(); showpopupmessage("Ready", "Done."); END_3: fclose(outputfile); outputfile = NULL; END_2: free(readbuf); END_1: for(i=0; isetText(""); SignalsTablewidget->setRowCount(0); } void UI_BDF2EDFwindow::showpopupmessage(const char *str1, const char *str2) { UI_Messagewindow popupmessage(str1, str2); } edfbrowser_153_source/PaxHeaders.2978/fourier.h0000644000175000001440000000013212251654530017773 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/fourier.h0000644000175000001440000000303112251654530017521 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef fouriertransform_INCLUDED #define fouriertransform_INCLUDED #include #ifdef __cplusplus extern "C" { #endif float fourier_transform_get_power_float(int freq, float *buf, int bufsize, float samplefreq); double fourier_transform_get_power_double(int freq, double *buf, int bufsize, double samplefreq); #ifdef __cplusplus } /* extern "C" */ #endif #endif edfbrowser_153_source/PaxHeaders.2978/edfbrowser.rc0000644000175000001440000000013212251654530020637 xustar000000000000000030 mtime=1386699096.488032464 30 atime=1386699096.488032464 30 ctime=1386699096.488032464 edfbrowser_153_source/edfbrowser.rc0000644000175000001440000000010112251654530020360 0ustar00novarausers00000000000000IDI_ICON1 ICON DISCARDABLE "images/edf.ico" edfbrowser_153_source/PaxHeaders.2978/print_to_bdf.cpp0000644000175000001440000000013212251654530021324 xustar000000000000000030 mtime=1386699096.478032517 30 atime=1386699096.478032517 30 ctime=1386699096.478032517 edfbrowser_153_source/print_to_bdf.cpp0000644000175000001440000010676012251654530021067 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "print_to_bdf.h" #if defined(__APPLE__) || defined(__MACH__) || defined(__APPLE_CC__) #define fopeno fopen #else #define fseeko fseeko64 #define ftello ftello64 #define fopeno fopen64 #endif void print_screen_to_bdf(UI_Mainwindow *mainwindow) { int i, j, k, p, n=0, records, records_written, signalcomps, duration_factor[MAXFILES], temp=0, bdfplus=0, tallen, annotationlist_nr=0, annotations_left=1, add_one_sec=0, annot_smp_per_record=16, type, len; long long duration, smpls_written[MAXSIGNALS], s2, preamble=0LL, smpls_preamble[MAXSIGNALS], taltime=0LL, l_temp, referencetime, annot_difftime=0LL; char path[MAX_PATH_LENGTH], scratchpad[512], datrecduration[8], *viewbuf; double frequency, frequency2, dig_value; FILE *outputfile; struct signalcompblock **signalcomp; union { signed int one_signed; signed short two_signed[2]; unsigned char four[4]; } wr_var; union { signed int one_signed; signed short two_signed[2]; unsigned char four[4]; } null_bytes[MAXSIGNALS]; union { unsigned int one; signed int one_signed; unsigned short two[2]; signed short two_signed[2]; unsigned char four[4]; } var; struct annotationblock *annotations_pntr; struct date_time_struct date_time; ///////////////////////////////////////////////////////////////////////// signalcomps = mainwindow->signalcomps; signalcomp = mainwindow->signalcomp; viewbuf = mainwindow->viewbuf; annotations_pntr = mainwindow->annotationlist[0]; if((!mainwindow->files_open)||(!signalcomps)) { QMessageBox messagewindow(QMessageBox::Critical, "Print to BDF", "Put a signal on the screen and try again."); messagewindow.exec(); return; } for(i=0; ifiles_open; i++) { if(mainwindow->edfheaderlist[i]->discontinuous) { QMessageBox messagewindow(QMessageBox::Critical, "Print to BDF", "Sorry, discontinues BDF/EDF files can not be printed to BDF.\n"); messagewindow.exec(); return; } if(mainwindow->edfheaderlist[i]->edfplus || mainwindow->edfheaderlist[i]->bdfplus) { bdfplus = 1; for(j=0; jedfheaderlist[i]->nr_annot_chns; j++) { if(mainwindow->edfheaderlist[i]->edfparam[mainwindow->edfheaderlist[i]->annot_ch[j]].smp_per_record>annot_smp_per_record) { annot_smp_per_record = mainwindow->edfheaderlist[i]->edfparam[mainwindow->edfheaderlist[i]->annot_ch[j]].smp_per_record; } } } } annot_smp_per_record += 11; taltime = mainwindow->edfheaderlist[mainwindow->sel_viewtime]->starttime_offset; duration = 0; for(i=0; iedfhdr->long_data_record_duration>duration) { duration = signalcomp[i]->edfhdr->long_data_record_duration; n = i; } } fseeko(signalcomp[n]->edfhdr->file_hdl, 244LL, SEEK_SET); if(fread(datrecduration, 8, 1, signalcomp[n]->edfhdr->file_hdl)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while reading from inputfile."); messagewindow.exec(); return; } temp = 0; for(i=0; iedfhdr->long_data_record_duration) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "This combination of files can not be printed to EDF\n" "because the quotient of the datarecordblock durations is not an integer."); messagewindow.exec(); return; } duration_factor[signalcomp[i]->filenum] = duration / signalcomp[i]->edfhdr->long_data_record_duration; temp += signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].smp_per_record; } 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[mainwindow->sel_viewtime]->filename, MAX_PATH_LENGTH - len); remove_extension_from_filename(path); strcat(path, "_screenprint.bdf"); strcpy(path, QFileDialog::getSaveFileName(0, "Print to 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(mainwindow->file_is_opened(path)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Error, selected file is in use."); messagewindow.exec(); return; } outputfile = fopeno(path, "wb"); if(outputfile==NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not create a file for writing."); messagewindow.exec(); return; } referencetime = mainwindow->edfheaderlist[mainwindow->sel_viewtime]->utc_starttime; if(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->viewtime<0) { if((-mainwindow->edfheaderlist[mainwindow->sel_viewtime]->viewtime) % TIME_DIMENSION) { preamble = TIME_DIMENSION - ((-mainwindow->edfheaderlist[mainwindow->sel_viewtime]->viewtime) % TIME_DIMENSION); referencetime--; add_one_sec = 1; } } else { preamble = mainwindow->edfheaderlist[mainwindow->sel_viewtime]->viewtime % TIME_DIMENSION; if(preamble) add_one_sec = 1; } referencetime += (mainwindow->edfheaderlist[mainwindow->sel_viewtime]->viewtime / TIME_DIMENSION); utc_to_date_time(referencetime, &date_time); /************************* write BDF-header ***************************************/ fseeko(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->file_hdl, 8LL, SEEK_SET); rewind(outputfile); if(bdfplus) { fputc(255, outputfile); fprintf(outputfile, "BIOSEMI"); if(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->edfplus || mainwindow->edfheaderlist[mainwindow->sel_viewtime]->bdfplus) { if(fread(scratchpad, 80, 1, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->file_hdl)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while reading from inputfile."); messagewindow.exec(); fclose(outputfile); return; } if(fwrite(scratchpad, 80, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } else { fprintf(outputfile, "X X X X "); if(fread(scratchpad, 80, 1, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->file_hdl)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while reading from inputfile."); messagewindow.exec(); fclose(outputfile); return; } if(fwrite(scratchpad, 72, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } fprintf(outputfile, "Startdate %02i-", date_time.day); switch(date_time.month) { case 1 : fprintf(outputfile, "JAN"); break; case 2 : fprintf(outputfile, "FEB"); break; case 3 : fprintf(outputfile, "MAR"); break; case 4 : fprintf(outputfile, "APR"); break; case 5 : fprintf(outputfile, "MAY"); break; case 6 : fprintf(outputfile, "JUN"); break; case 7 : fprintf(outputfile, "JUL"); break; case 8 : fprintf(outputfile, "AUG"); break; case 9 : fprintf(outputfile, "SEP"); break; case 10 : fprintf(outputfile, "OCT"); break; case 11 : fprintf(outputfile, "NOV"); break; case 12 : fprintf(outputfile, "DEC"); break; default : fprintf(outputfile, "ERR"); break; } fprintf(outputfile, "-%04i ", date_time.year); if(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->edfplus || mainwindow->edfheaderlist[mainwindow->sel_viewtime]->bdfplus) { if(fread(scratchpad, 80, 1, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->file_hdl)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while reading from inputfile."); messagewindow.exec(); fclose(outputfile); return; } if(scratchpad[10]=='X') { if(fwrite(scratchpad + 12, 58, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } else { if(fwrite(scratchpad + 22, 58, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } } else { fprintf(outputfile, "X X X "); if(fread(scratchpad, 80, 1, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->file_hdl)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while reading from inputfile."); messagewindow.exec(); fclose(outputfile); return; } if(fwrite(scratchpad + 28, 52, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } } else { if(fread(scratchpad, 160, 1, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->file_hdl)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while reading from inputfile."); messagewindow.exec(); fclose(outputfile); return; } fputc(255, outputfile); fprintf(outputfile, "BIOSEMI"); if(fwrite(scratchpad, 160, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } fprintf(outputfile, "%02i.%02i.%02i%02i.%02i.%02i", date_time.day, date_time.month, date_time.year % 100, date_time.hour, date_time.minute, date_time.second); fprintf(outputfile, "%-8i", (signalcomps + bdfplus) * 256 + 256); if(bdfplus) { fprintf(outputfile, "BDF+C"); for(i=0; i<39; i++) fputc(' ', outputfile); } else { for(i=0; i<44; i++) fputc(' ', outputfile); } records = (int)(mainwindow->pagetime / duration); if(add_one_sec) { records += TIME_DIMENSION / duration; } fprintf(outputfile, "%-8i", records); if(fwrite(datrecduration, 8, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } fprintf(outputfile, "%-4i", signalcomps + bdfplus); for(i=0; isignallabel); strcat(scratchpad, " "); if(fwrite(scratchpad, 16, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } if(bdfplus) { if(fwrite("BDF Annotations ", 16, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } for(i=0; iedfhdr->edfparam[signalcomp[i]->edfsignal[0]].transducer, 80, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } if(bdfplus) { for(i=0; i<80; i++) fputc(' ', outputfile); } for(i=0; iphysdimension); strcat(scratchpad, " "); if(fwrite(scratchpad, 8, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } if(bdfplus) { for(i=0; i<8; i++) fputc(' ', outputfile); } for(i=0; iecg_filter == NULL) && (signalcomp[i]->zratio_filter == NULL)) { fseeko(signalcomp[i]->edfhdr->file_hdl, (long long)((signalcomp[i]->edfsignal[0] * 8) + (104 * signalcomp[i]->edfhdr->edfsignals) + 256), SEEK_SET); if(fread(scratchpad, 8, 1, signalcomp[i]->edfhdr->file_hdl)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while reading from inputfile."); messagewindow.exec(); fclose(outputfile); return; } if(fwrite(scratchpad, 8, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } if(signalcomp[i]->ecg_filter != NULL) { if(fwrite("0 ", 8, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } if(signalcomp[i]->zratio_filter != NULL) { if(fwrite("-1 ", 8, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } } if(bdfplus) { if(fwrite("-1 ", 8, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } for(i=0; iecg_filter == NULL) && (signalcomp[i]->zratio_filter == NULL)) { fseeko(signalcomp[i]->edfhdr->file_hdl, (long long)((signalcomp[i]->edfsignal[0] * 8) + (112 * signalcomp[i]->edfhdr->edfsignals) + 256), SEEK_SET); if(fread(scratchpad, 8, 1, signalcomp[i]->edfhdr->file_hdl)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while reading from inputfile."); messagewindow.exec(); fclose(outputfile); return; } if(fwrite(scratchpad, 8, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } if(signalcomp[i]->ecg_filter != NULL) { if(fwrite("1000 ", 8, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } if(signalcomp[i]->zratio_filter != NULL) { if(fwrite("1 ", 8, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } } if(bdfplus) { if(fwrite("1 ", 8, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } for(i=0; iecg_filter == NULL) && (signalcomp[i]->zratio_filter == NULL)) { fprintf(outputfile, "%-8i", signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].dig_min); if(signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].dig_min<0) { null_bytes[i].one_signed = 0; } else { null_bytes[i].one_signed = signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].dig_min; } } else { if(fwrite("-8388608", 8, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } null_bytes[i].one_signed = -8388608; } } if(bdfplus) { if(fwrite("-8388608", 8, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } for(i=0; iecg_filter == NULL) && (signalcomp[i]->zratio_filter == NULL)) { fprintf(outputfile, "%-8i", signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].dig_max); } else { if(fwrite("8388607 ", 8, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } } if(bdfplus) { if(fwrite("8388607 ", 8, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } for(i=0; iedfhdr->edfparam[signalcomp[i]->edfsignal[0]].prefilter); strcat(scratchpad, " "); for(p = strlen(scratchpad) - 1; p>=0; p--) { if(scratchpad[p]!=' ') break; } p++; if(p) p++; for(j=0; jfilter_cnt; j++) { if(signalcomp[i]->filter[j]->is_LPF == 1) { p += sprintf(scratchpad + p, "LP:%f", signalcomp[i]->filter[j]->cutoff_frequency); } if(signalcomp[i]->filter[j]->is_LPF == 0) { p += sprintf(scratchpad + p, "HP:%f", signalcomp[i]->filter[j]->cutoff_frequency); } for(k=(p-1); k>0; k--) { if(scratchpad[k]!='0') break; } if(scratchpad[k]=='.') scratchpad[k] = 0; else scratchpad[k+1] = 0; strcat(scratchpad, "Hz "); p = strlen(scratchpad); if(p>80) break; } for(j=0; jfidfilter_cnt; j++) { type = signalcomp[i]->fidfilter_type[j]; frequency = signalcomp[i]->fidfilter_freq[j]; frequency2 = signalcomp[i]->fidfilter_freq2[j]; if(type == 0) { p += sprintf(scratchpad + p, "HP:%f", frequency); } if(type == 1) { p += sprintf(scratchpad + p, "LP:%f", frequency); } if(type == 2) { p += sprintf(scratchpad + p, "N:%f", frequency); } if(type == 3) { p += sprintf(scratchpad + p, "BP:%f", frequency); } if(type == 4) { p += sprintf(scratchpad + p, "BS:%f", frequency); } for(k=(p-1); k>0; k--) { if(scratchpad[k]!='0') break; } if(scratchpad[k]=='.') scratchpad[k] = 0; else scratchpad[k+1] = 0; p = strlen(scratchpad); if((type == 3) || (type == 4)) { p += sprintf(scratchpad + p, "-%f", frequency2); for(k=(p-1); k>0; k--) { if(scratchpad[k]!='0') break; } if(scratchpad[k]=='.') scratchpad[k] = 0; else scratchpad[k+1] = 0; } strcat(scratchpad, "Hz "); p = strlen(scratchpad); if(p>80) break; } for(j=0; jravg_filter_cnt; j++) { if(signalcomp[i]->ravg_filter_type[j] == 0) { p += sprintf(scratchpad + p, "HP:%iSmpls ", signalcomp[i]->ravg_filter[j]->size); } if(signalcomp[i]->ravg_filter_type[j] == 1) { p += sprintf(scratchpad + p, "LP:%iSmpls ", signalcomp[i]->ravg_filter[j]->size); } p = strlen(scratchpad); if(p>80) break; } if(signalcomp[i]->ecg_filter != NULL) { p += sprintf(scratchpad + p, "ECG:HR "); } if(signalcomp[i]->zratio_filter != NULL) { p += sprintf(scratchpad + p, "Z-ratio "); } for(;p<81; p++) { scratchpad[p] = ' '; } if(fwrite(scratchpad, 80, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } if(bdfplus) { for(i=0; i<80; i++) fputc(' ', outputfile); } for(i=0; iedfhdr->edfparam[signalcomp[i]->edfsignal[0]].smp_per_record * duration_factor[signalcomp[i]->filenum]); } if(bdfplus) { fprintf(outputfile, "%-8i", annot_smp_per_record); } for(i=0; iprint_to_edf_active = 1; mainwindow->setup_viewbuf(); viewbuf = mainwindow->viewbuf; if(viewbuf==NULL) { fclose(outputfile); return; } for(i=0; iedfhdr->long_data_record_duration / signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].smp_per_record); } QApplication::setOverrideCursor(Qt::WaitCursor); for(records_written=0; records_writtenprocessEvents(); for(i=0; iedfhdr->edfparam[signalcomp[i]->edfsignal[0]].smp_per_record * duration_factor[signalcomp[i]->filenum]; k++) { if(smpls_preamble[i]) { smpls_preamble[i]--; fputc(null_bytes[i].four[0], outputfile); fputc(null_bytes[i].four[1], outputfile); if(fputc(null_bytes[i].four[2], outputfile)==EOF) { QApplication::restoreOverrideCursor(); QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } else { dig_value = 0; s2 = smpls_written[i] + signalcomp[i]->sample_timeoffset - signalcomp[i]->sample_start; for(j=0; jnum_of_signals; j++) { if((smpls_written[i]sample_stop)&&(s2>=0)) { if(signalcomp[i]->edfhdr->bdf) { var.two[0] = *((unsigned short *)( viewbuf + signalcomp[i]->viewbufoffset + (signalcomp[i]->edfhdr->recordsize * (s2 / signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[j]].smp_per_record)) + signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[j]].buf_offset + ((s2 % signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[j]].smp_per_record) * 3))); var.four[2] = *((unsigned char *)( viewbuf + signalcomp[i]->viewbufoffset + (signalcomp[i]->edfhdr->recordsize * (s2 / signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[j]].smp_per_record)) + signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[j]].buf_offset + ((s2 % signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[j]].smp_per_record) * 3) + 2)); if(var.four[2]&0x80) { var.four[3] = 0xff; } else { var.four[3] = 0x00; } temp = var.one_signed; } if(signalcomp[i]->edfhdr->edf) { temp = *(((short *)( viewbuf + signalcomp[i]->viewbufoffset + (signalcomp[i]->edfhdr->recordsize * (s2 / signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[j]].smp_per_record)) + signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[j]].buf_offset)) + (s2 % signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[j]].smp_per_record)); } temp += signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[j]].offset; temp *= signalcomp[i]->factor[j]; temp -= signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[j]].offset; } else { temp = 0; } dig_value += temp; } for(p=0; pfilter_cnt; p++) { if(smpls_written[i]==signalcomp[i]->sample_start) { if(mainwindow->edfheaderlist[signalcomp[i]->filenum]->viewtime==0) { reset_filter(dig_value, signalcomp[i]->filter[p]); } else { signalcomp[i]->filter[p]->old_input = signalcomp[i]->filterpreset_a[p]; signalcomp[i]->filter[p]->old_output = signalcomp[i]->filterpreset_b[p]; } } dig_value = first_order_filter(dig_value, signalcomp[i]->filter[p]); } for(p=0; pravg_filter_cnt; p++) { if(smpls_written[i]==signalcomp[i]->sample_start) { if(mainwindow->edfheaderlist[signalcomp[i]->filenum]->viewtime!=0) { ravg_filter_restore_buf(signalcomp[i]->ravg_filter[p]); } } dig_value = run_ravg_filter(dig_value, signalcomp[i]->ravg_filter[p]); } for(p=0; pfidfilter_cnt; p++) { if(smpls_written[i]==signalcomp[i]->sample_start) { if(mainwindow->edfheaderlist[signalcomp[i]->filenum]->viewtime!=0) { memcpy(signalcomp[i]->fidbuf[p], signalcomp[i]->fidbuf2[p], fid_run_bufsize(signalcomp[i]->fid_run[p])); } } dig_value = signalcomp[i]->fidfuncp[p](signalcomp[i]->fidbuf[p], dig_value); } if(signalcomp[i]->ecg_filter != NULL) { if(smpls_written[i]==signalcomp[i]->sample_start) { if(mainwindow->edfheaderlist[signalcomp[i]->filenum]->viewtime != 0) { ecg_filter_restore_buf(signalcomp[i]->ecg_filter); } } dig_value = run_ecg_filter(dig_value, signalcomp[i]->ecg_filter); dig_value = (dig_value * signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].bitvalue * 16777.216) - 8388608.0; } if(signalcomp[i]->zratio_filter != NULL) { if(smpls_written[i]==signalcomp[i]->sample_start) { if(mainwindow->edfheaderlist[signalcomp[i]->filenum]->viewtime != 0) { zratio_filter_restore_buf(signalcomp[i]->zratio_filter); } } dig_value = run_zratio_filter(dig_value, signalcomp[i]->zratio_filter); dig_value = dig_value * signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].bitvalue * 8388608.0; } if((smpls_written[i]>=signalcomp[i]->sample_start)&&(smpls_written[i]sample_stop)) { wr_var.one_signed = dig_value; if((signalcomp[i]->ecg_filter == NULL) && (signalcomp[i]->zratio_filter == NULL)) { if(wr_var.one_signed>signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].dig_max) { wr_var.one_signed = signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].dig_max; } if(wr_var.one_signededfhdr->edfparam[signalcomp[i]->edfsignal[0]].dig_min) { wr_var.one_signed = signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].dig_min; } } else { if(wr_var.one_signed > 8388607) { wr_var.one_signed = 8388607; } if(wr_var.one_signed < -8388608) { wr_var.one_signed = -8388608; } } fputc(wr_var.four[0], outputfile); fputc(wr_var.four[1], outputfile); if(fputc(wr_var.four[2], outputfile)==EOF) { QApplication::restoreOverrideCursor(); QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } else { fputc(null_bytes[i].four[0], outputfile); fputc(null_bytes[i].four[1], outputfile); if(fputc(null_bytes[i].four[2], outputfile)==EOF) { QApplication::restoreOverrideCursor(); QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while writing to outputfile."); messagewindow.exec(); fclose(outputfile); return; } } smpls_written[i]++; } } } if(bdfplus) { tallen = fprintf(outputfile, "+%i.%07i", (int)(taltime / TIME_DIMENSION), (int)(taltime % TIME_DIMENSION)); fputc(20, outputfile); fputc(20, outputfile); fputc(0, outputfile); tallen += 3; if(annotations_left) { if(mainwindow->viewtime_sync==VIEWTIME_SYNCED_ABSOLUT) { annot_difftime = (referencetime - mainwindow->edfheaderlist[annotationlist_nr]->utc_starttime) * TIME_DIMENSION; } if(mainwindow->viewtime_sync==VIEWTIME_SYNCED_OFFSET) { annot_difftime = (referencetime - mainwindow->edfheaderlist[mainwindow->sel_viewtime]->utc_starttime) * TIME_DIMENSION; } if((mainwindow->viewtime_sync==VIEWTIME_UNSYNCED) || (mainwindow->viewtime_sync==VIEWTIME_USER_DEF_SYNCED)) { annot_difftime = (referencetime - mainwindow->edfheaderlist[mainwindow->sel_viewtime]->utc_starttime) * TIME_DIMENSION; annot_difftime += (mainwindow->edfheaderlist[annotationlist_nr]->viewtime - mainwindow->edfheaderlist[mainwindow->sel_viewtime]->viewtime); } if(annotationlist_nr != mainwindow->sel_viewtime) { annot_difftime -= mainwindow->edfheaderlist[mainwindow->sel_viewtime]->starttime_offset; annot_difftime += mainwindow->edfheaderlist[annotationlist_nr]->starttime_offset; } } while(annotations_left) { while(!annotations_pntr) { annotationlist_nr++; if(annotationlist_nr>=mainwindow->files_open) { annotations_left = 0; annotations_pntr = NULL; break; } annotations_pntr = mainwindow->annotationlist[annotationlist_nr]; if(mainwindow->viewtime_sync==VIEWTIME_SYNCED_ABSOLUT) { annot_difftime = (referencetime - mainwindow->edfheaderlist[annotationlist_nr]->utc_starttime) * TIME_DIMENSION; } if(mainwindow->viewtime_sync==VIEWTIME_SYNCED_OFFSET) { annot_difftime = (referencetime - mainwindow->edfheaderlist[mainwindow->sel_viewtime]->utc_starttime) * TIME_DIMENSION; } if((mainwindow->viewtime_sync==VIEWTIME_UNSYNCED) || (mainwindow->viewtime_sync==VIEWTIME_USER_DEF_SYNCED)) { annot_difftime = (referencetime - mainwindow->edfheaderlist[mainwindow->sel_viewtime]->utc_starttime) * TIME_DIMENSION; annot_difftime += (mainwindow->edfheaderlist[annotationlist_nr]->viewtime - mainwindow->edfheaderlist[mainwindow->sel_viewtime]->viewtime); } if(annotationlist_nr != mainwindow->sel_viewtime) { annot_difftime -= mainwindow->edfheaderlist[mainwindow->sel_viewtime]->starttime_offset; annot_difftime += mainwindow->edfheaderlist[annotationlist_nr]->starttime_offset; } } if(!annotations_left) break; if(annotations_pntr) { l_temp = annotations_pntr->onset - annot_difftime; if((l_temp >= 0LL) && (l_temp < (mainwindow->pagetime + TIME_DIMENSION))) { tallen += fprintf(outputfile, "%+i.%07i", (int)(l_temp / TIME_DIMENSION), (int)(l_temp % TIME_DIMENSION)); if(annotations_pntr->duration[0]!=0) { fputc(21, outputfile); tallen++; tallen += fprintf(outputfile, "%s", annotations_pntr->duration); } fputc(20, outputfile); tallen++; tallen += fprintf(outputfile, "%s", annotations_pntr->annotation); fputc(20, outputfile); fputc(0, outputfile); tallen += 2; annotations_pntr = annotations_pntr->next_annotation; break; } else { annotations_pntr = annotations_pntr->next_annotation; continue; } } } for(j=tallen; j<(annot_smp_per_record * 3); j++) { fputc(0, outputfile); } taltime += duration; } } QApplication::restoreOverrideCursor(); fclose(outputfile); } edfbrowser_153_source/PaxHeaders.2978/ascii_export.cpp0000644000175000001440000000013212251654530021344 xustar000000000000000030 mtime=1386699096.476032527 30 atime=1386699096.476032527 30 ctime=1386699096.476032527 edfbrowser_153_source/ascii_export.cpp0000644000175000001440000006200712251654530021102 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "ascii_export.h" #if defined(__APPLE__) || defined(__MACH__) || defined(__APPLE_CC__) #define fopeno fopen #else #define fseeko fseeko64 #define ftello ftello64 #define fopeno fopen64 #endif UI_AsciiExportwindow::UI_AsciiExportwindow(QWidget *w_parent) { int i; mainwindow = (UI_Mainwindow *)w_parent; AsciiExportDialog = new QDialog; AsciiExportDialog->setMinimumSize(QSize(800, 180)); AsciiExportDialog->setMaximumSize(QSize(800, 180)); AsciiExportDialog->setWindowTitle("Export to ASCII"); AsciiExportDialog->setModal(TRUE); AsciiExportDialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); filelist = new QListWidget(AsciiExportDialog); filelist->setGeometry(QRect(10, 10, 780, 75)); filelist->setSelectionBehavior(QAbstractItemView::SelectRows); filelist->setSelectionMode(QAbstractItemView::SingleSelection); for(i=0; ifiles_open; i++) { if((mainwindow->edfheaderlist[i]->edf)||(mainwindow->edfheaderlist[i]->bdf)) { new QListWidgetItem(QString::fromLocal8Bit(mainwindow->edfheaderlist[i]->filename), filelist); } } ExportButton = new QPushButton(AsciiExportDialog); ExportButton->setGeometry(QRect(10, 140, 100, 25)); ExportButton->setText("Export"); CloseButton = new QPushButton(AsciiExportDialog); CloseButton->setGeometry(QRect(690, 140, 100, 25)); CloseButton->setText("Close"); QObject::connect(CloseButton, SIGNAL(clicked()), AsciiExportDialog, SLOT(close())); QObject::connect(ExportButton, SIGNAL(clicked()), this, SLOT(ExportButtonClicked())); filelist->setCurrentRow(mainwindow->files_open - 1); AsciiExportDialog->exec(); } void UI_AsciiExportwindow::ExportButtonClicked() { int i, j, k, m, p, r, n, edfsignals, datarecords, datarecordswritten, recordsize, recordfull, edfplus, bdf, bdfplus=0, samplesize, annot_ch[256], nr_annot_chns=0, skip, max, onset, duration, zero, max_tal_ln, len, progress_steps; char path[MAX_PATH_LENGTH], ascii_path[MAX_PATH_LENGTH], *edf_hdr, *scratchpad, *cnv_buf, *time_in_txt, *duration_in_txt, str[1024]; union { unsigned int one; signed int one_signed; unsigned short two[2]; signed short two_signed[2]; unsigned char four[4]; } var; FILE *inputfile, *outputfile, *annotationfile; double data_record_duration, elapsedtime, time_tmp, d_tmp, value_tmp; if(!mainwindow->files_open) { AsciiExportDialog->close(); return; } ExportButton->setEnabled(FALSE); CloseButton->setEnabled(FALSE); for(i=0; ifiles_open; i++) { if(!strcmp(mainwindow->edfheaderlist[i]->filename, filelist->item(filelist->currentRow())->text().toLocal8Bit().data())) { break; } } if(i==mainwindow->files_open) return; n = i; inputfile = mainwindow->edfheaderlist[n]->file_hdl; 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); strcat(path, "_data.txt"); strcpy(path, QFileDialog::getSaveFileName(0, "Export to ASCII", QString::fromLocal8Bit(path), "Text files (*.txt *.TXT)").toLocal8Bit().data()); if(!strcmp(path, "")) { AsciiExportDialog->close(); return; } get_directory_from_path(mainwindow->recent_savedir, path, MAX_PATH_LENGTH); if(mainwindow->file_is_opened(path)) { QMessageBox messagewindow(QMessageBox::Critical, "Save file", "Error, selected file is in use."); messagewindow.exec(); AsciiExportDialog->close(); return; } if(!(strcmp(path + strlen(path) - 9, "_data.txt"))) { path[strlen(path) - 9] = 0; } scratchpad = (char *)calloc(1, 128); if(scratchpad==NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Malloc error! (scratchpad)."); messagewindow.exec(); AsciiExportDialog->close(); return; } if(fseeko(inputfile, 0xfcLL, SEEK_SET)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "File read error."); messagewindow.exec(); AsciiExportDialog->close(); return; } if(fread(scratchpad, 4, 1, inputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "File read error."); messagewindow.exec(); AsciiExportDialog->close(); return; } scratchpad[4] = 0; edfsignals = atoi(scratchpad); edf_hdr = (char *)calloc(1, (edfsignals + 1) * 256); if(edf_hdr==NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Malloc error! (edf_hdr)"); messagewindow.exec(); AsciiExportDialog->close(); return; } rewind(inputfile); if(fread(edf_hdr, (edfsignals + 1) * 256, 1, inputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "File read error."); messagewindow.exec(); free(edf_hdr); AsciiExportDialog->close(); return; } for(i=0; i<((edfsignals+1)*256); i++) { if(edf_hdr[i]==',') edf_hdr[i] = '\''; /* replace all comma's in header by single quotes because they */ } /* interfere with the comma-separated txt-files */ strncpy(scratchpad, edf_hdr + 0xec, 8); scratchpad[8] = 0; datarecords = atoi(scratchpad); strncpy(scratchpad, edf_hdr + 0xf4, 8); scratchpad[8] = 0; data_record_duration = atof(scratchpad); nr_annot_chns = 0; if(((signed char *)edf_hdr)[0]==-1) { bdf = 1; samplesize = 3; edfplus = 0; if((strncmp(edf_hdr + 0xc0, "BDF+C ", 10))&&(strncmp(edf_hdr + 0xc0, "BDF+D ", 10))) { bdfplus = 0; } else { bdfplus = 1; for(i=0; i255) break; } } } } else { bdf = 0; samplesize = 2; if((strncmp(edf_hdr + 0xc0, "EDF+C ", 10))&&(strncmp(edf_hdr + 0xc0, "EDF+D ", 10))) { edfplus = 0; } else { edfplus = 1; for(i=0; i255) break; } } } } edfparamascii = (struct asciiedfparamblock *)calloc(1, sizeof(struct asciiedfparamblock[edfsignals])); if(edfparamascii==NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Malloc error! (edfparam)"); messagewindow.exec(); free(edf_hdr); AsciiExportDialog->close(); return; } recordsize = 0; for(i=0; iclose(); return; } free(scratchpad); max_tal_ln = 0; for(r=0; rclose(); return; } duration_in_txt = (char *)calloc(1, max_tal_ln + 3); if(duration_in_txt==NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Malloc error! (duration_in_txt)"); messagewindow.exec(); free(scratchpad); free(cnv_buf); free(edf_hdr); free(edfparamascii); AsciiExportDialog->close(); return; } time_in_txt = (char *)calloc(1, max_tal_ln + 3); if(time_in_txt==NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Malloc error! (time_in_txt)"); messagewindow.exec(); free(duration_in_txt); free(scratchpad); free(cnv_buf); free(edf_hdr); free(edfparamascii); AsciiExportDialog->close(); return; } /***************** write header ******************************/ strcpy(ascii_path, path); remove_extension_from_filename(ascii_path); strcat(ascii_path, "_header.txt"); outputfile = fopeno(ascii_path, "wb"); if(outputfile==NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Error, can not open headerfile for writing."); messagewindow.exec(); free(edf_hdr); free(edfparamascii); free(cnv_buf); free(time_in_txt); free(duration_in_txt); free(scratchpad); AsciiExportDialog->close(); return; } fprintf(outputfile, "Version,Subject,Recording,Startdate,Startime,Bytes,Reserved,NumRec,Duration,NumSig\n"); if(bdf) { fprintf(outputfile, ".%.7s,", edf_hdr + 1); } else { fprintf(outputfile, "%.8s,", edf_hdr); } fprintf(outputfile, "%.80s,", edf_hdr + 8); fprintf(outputfile, "%.80s,", edf_hdr + 88); fprintf(outputfile, "%.8s,", edf_hdr + 168); fprintf(outputfile, "%.8s,", edf_hdr + 176); fprintf(outputfile, "%.8s,", edf_hdr + 184); fprintf(outputfile, "%.44s,", edf_hdr + 192); fprintf(outputfile, "%i,", datarecords); fprintf(outputfile, "%.8s,", edf_hdr + 244); snprintf(scratchpad, 128, "%.4s", edf_hdr + 252); fprintf(outputfile, "%i\n", atoi(scratchpad) - nr_annot_chns); fclose(outputfile); /***************** write signals ******************************/ strcpy(ascii_path, path); remove_extension_from_filename(ascii_path); strcat(ascii_path, "_signals.txt"); outputfile = fopeno(ascii_path, "wb"); if(outputfile==NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Error, can not open signalfile for writing."); messagewindow.exec(); free(edf_hdr); free(edfparamascii); free(cnv_buf); free(time_in_txt); free(duration_in_txt); free(scratchpad); AsciiExportDialog->close(); return; } fprintf(outputfile, "Signal,Label,Transducer,Units,Min,Max,Dmin,Dmax,PreFilter,Smp/Rec,Reserved\n"); for(i=0; iclose(); return; } fprintf(annotationfile, "Onset,Duration,Annotation\n"); /***************** write data ******************************/ strcpy(ascii_path, path); remove_extension_from_filename(ascii_path); strcat(ascii_path, "_data.txt"); outputfile = fopeno(ascii_path, "wb"); if(outputfile==NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Error, can not open datafile for writing."); messagewindow.exec(); fclose(annotationfile); free(edf_hdr); free(edfparamascii); free(cnv_buf); free(time_in_txt); free(duration_in_txt); free(scratchpad); AsciiExportDialog->close(); return; } fprintf(outputfile, "Time"); for(i=0; i<(edfsignals-nr_annot_chns); i++) { fprintf(outputfile, ",%i", i + 1); } if(fputc('\n', outputfile)==EOF) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred when writing to outputfile."); messagewindow.exec(); fclose(annotationfile); fclose(outputfile); free(edf_hdr); free(edfparamascii); free(cnv_buf); free(time_in_txt); free(duration_in_txt); free(scratchpad); AsciiExportDialog->close(); return; } if(fseeko(inputfile, (long long)((edfsignals + 1) * 256), SEEK_SET)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred when reading from inputfile."); messagewindow.exec(); fclose(annotationfile); fclose(outputfile); free(edf_hdr); free(edfparamascii); free(cnv_buf); free(time_in_txt); free(duration_in_txt); free(scratchpad); AsciiExportDialog->close(); return; } /***************** start data conversion ******************************/ QProgressDialog progress("Writing file...", "Abort", 0, datarecords); progress.setWindowModality(Qt::WindowModal); progress.setMinimumDuration(200); progress_steps = datarecords / 100; if(progress_steps < 1) { progress_steps = 1; } datarecordswritten = 0; for(i=0; iprocessEvents(); if(progress.wasCanceled() == TRUE) { break; } } for(j=0; jclose(); return; } if(edfplus || bdfplus) { max = edfparamascii[annot_ch[0]].smp_per_record * samplesize; p = edfparamascii[annot_ch[0]].buf_offset * samplesize; /* extract time from datarecord */ for(k=0; kmax_tal_ln) { progress.reset(); snprintf(str, 256, "Error, TAL in record %i exceeds my buffer.", datarecordswritten + 1); QMessageBox messagewindow(QMessageBox::Critical, "Error", str); messagewindow.exec(); fclose(annotationfile); fclose(outputfile); free(edf_hdr); free(edfparamascii); free(cnv_buf); free(time_in_txt); free(duration_in_txt); free(scratchpad); AsciiExportDialog->close(); return; } scratchpad[k] = cnv_buf[p + k]; if(scratchpad[k]==20) break; } scratchpad[k] = 0; elapsedtime = atof(scratchpad); /* process annotations */ for(r=0; rmax_tal_ln) { progress.reset(); snprintf(str, 256, "Error, TAL in record %i exceeds my buffer.", datarecordswritten + 1); QMessageBox messagewindow(QMessageBox::Critical, "Error", str); messagewindow.exec(); fclose(annotationfile); fclose(outputfile); free(edf_hdr); free(edfparamascii); free(cnv_buf); free(time_in_txt); free(duration_in_txt); free(scratchpad); AsciiExportDialog->close(); return; } scratchpad[n] = cnv_buf[p + k]; if(scratchpad[n]==0) { n = 0; onset = 0; duration = 0; time_in_txt[0] = 0; duration_in_txt[0] = 0; scratchpad[0] = 0; zero++; continue; } else zero = 0; if(zero>1) break; if(scratchpad[n]==20) { if(duration) { scratchpad[n] = 0; strcpy(duration_in_txt, scratchpad); n = 0; duration = 0; scratchpad[0] = 0; continue; } else if(onset) { scratchpad[n] = 0; if(n) { utf8_to_latin1(scratchpad); for(m=0; mmax_tal_ln) { progress.reset(); snprintf(str, 256, "Error, TAL in record %i exceeds my buffer.", datarecordswritten + 1); QMessageBox messagewindow(QMessageBox::Critical, "Error", str); messagewindow.exec(); fclose(annotationfile); fclose(outputfile); free(edf_hdr); free(edfparamascii); free(cnv_buf); free(time_in_txt); free(duration_in_txt); free(scratchpad); AsciiExportDialog->close(); return; } } } } else elapsedtime = datarecordswritten * data_record_duration; /* done with timekeeping and annotations, continue with the data */ do { time_tmp = 10000000000.0; for(j=0; j(time_tmp-0.00000000000001))&&(edfparamascii[j].smp_writtenclose(); return; } recordfull = 1; for(j=0; jclose(); } edfbrowser_153_source/PaxHeaders.2978/edf_annotations.cpp0000644000175000001440000000013212251654530022026 xustar000000000000000030 mtime=1386699096.477032522 30 atime=1386699096.477032522 30 ctime=1386699096.477032522 edfbrowser_153_source/edf_annotations.cpp0000644000175000001440000004700112251654530021561 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "edf_annotations.h" #if defined(__APPLE__) || defined(__MACH__) || defined(__APPLE_CC__) #define fopeno fopen #else #define fseeko fseeko64 #define ftello ftello64 #define fopeno fopen64 #endif 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; iedfparam[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; jedfparam[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; iprocessEvents(); 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=TIME_DIMENSION) { error = 2; goto END; } else { edf_hdr->starttime_offset = time_tmp; } } elapsedtime = time_tmp; error = 0; break; } } } } for(k=0; k1) { 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; jannotation[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; j126)) { 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; kfile_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); } int EDF_annotations::is_duration_number(char *str) { int i, l, hasdot = 0; l = strlen(str); if(!l) return(1); if((str[0] == '.')||(str[l-1] == '.')) return(1); for(i=0; i57)) return(1); } } return(0); } int EDF_annotations::is_onset_number(char *str) { int i, l, hasdot = 0; l = strlen(str); if(l<2) return(1); if((str[0]!='+')&&(str[0]!='-')) return(1); if((str[1] == '.')||(str[l-1] == '.')) return(1); for(i=1; i57)) return(1); } } return(0); } long long EDF_annotations::get_long_time(char *str) { int i, len, hasdot=0, dotposition=0; long long value=0, radix; str = str + 1; len = strlen(str); for(i=0; i=0; i--) { value += ((long long)(str[i] - 48)) * radix; radix *= 10; } radix = TIME_DIMENSION / 10; for(i=dotposition+1; i=0; i--) { value += ((long long)(str[i] - 48)) * radix; radix *= 10; } } if(str[-1]=='-') value = -value; return(value); } int EDF_annotations::check_device(char *str) { int error = 1; if(strlen(str) < 29) return(1); if(!strncmp(str, "Nihon Kohden EEG-1100A V01.00", 29)) error = 0; if(!strncmp(str, "Nihon Kohden EEG-1100B V01.00", 29)) error = 0; if(!strncmp(str, "Nihon Kohden EEG-1100C V01.00", 29)) error = 0; if(!strncmp(str, "Nihon Kohden QI-403A V01.00", 29)) error = 0; if(!strncmp(str, "Nihon Kohden QI-403A V02.00", 29)) error = 0; if(!strncmp(str, "Nihon Kohden EEG-2100 V01.00", 29)) error = 0; if(!strncmp(str, "Nihon Kohden EEG-2100 V02.00", 29)) error = 0; if(!strncmp(str, "Nihon Kohden DAE-2100D V01.30", 29)) error = 0; if(!strncmp(str, "Nihon Kohden DAE-2100D V02.00", 29)) error = 0; // if(!strncmp(str, "Nihon Kohden EEG-1200A V01.00", 29)) error = 0; return(error); } edfbrowser_153_source/PaxHeaders.2978/ascii2edf.cpp0000644000175000001440000000013212251654530020504 xustar000000000000000030 mtime=1386699096.476032527 30 atime=1386699096.476032527 30 ctime=1386699096.476032527 edfbrowser_153_source/ascii2edf.cpp0000644000175000001440000013131412251654530020240 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "ascii2edf.h" #if defined(__APPLE__) || defined(__MACH__) || defined(__APPLE_CC__) #define fopeno fopen #else #define fseeko fseeko64 #define ftello ftello64 #define fopeno fopen64 #endif UI_ASCII2EDFapp::UI_ASCII2EDFapp(char *recent_dir, char *save_dir) { recent_opendir = recent_dir; recent_savedir = save_dir; autoPhysicalMaximum = 1; edf_format = 1; ascii2edfDialog = new QDialog; ascii2edfDialog->setMinimumSize(QSize(600, 440)); ascii2edfDialog->setMaximumSize(QSize(600, 440)); ascii2edfDialog->setWindowTitle("ASCII to EDF/BDF converter"); ascii2edfDialog->setModal(TRUE); ascii2edfDialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); SeparatorLabel = new QLabel(ascii2edfDialog); SeparatorLabel->setGeometry(QRect(20, 20, 140, 16)); SeparatorLabel->setText("Column separator"); NumsignalsLabel = new QLabel(ascii2edfDialog); NumsignalsLabel->setGeometry(QRect(20, 50, 140, 16)); NumsignalsLabel->setText("Number of columns"); DatastartLabel = new QLabel(ascii2edfDialog); DatastartLabel->setGeometry(QRect(20, 80, 140, 16)); DatastartLabel->setText("Data starts at line"); SamplefreqLabel = new QLabel(ascii2edfDialog); SamplefreqLabel->setGeometry(QRect(20, 110, 140, 16)); SamplefreqLabel->setText("Samplefrequency"); PatientnameLabel = new QLabel(ascii2edfDialog); PatientnameLabel->setGeometry(QRect(20, 140, 140, 16)); PatientnameLabel->setText("Subject name"); RecordingLabel = new QLabel(ascii2edfDialog); RecordingLabel->setGeometry(QRect(20, 170, 140, 16)); RecordingLabel->setText("Recording"); DatetimeLabel = new QLabel(ascii2edfDialog); DatetimeLabel->setGeometry(QRect(20, 200, 140, 16)); DatetimeLabel->setText("Startdate and time"); autoPhysicalMaximumLabel = new QLabel(ascii2edfDialog); autoPhysicalMaximumLabel->setGeometry(QRect(360, 200, 180, 16)); autoPhysicalMaximumLabel->setText("Auto detect physical maximum"); SignalsLabel = new QLabel(ascii2edfDialog); SignalsLabel->setGeometry(QRect(20, 240, 140, 16)); SignalsLabel->setText("Signals"); groupbox1 = new QGroupBox(ascii2edfDialog); groupbox1->setGeometry(QRect(330, 20, 160, 90)); groupbox1->setTitle("Output format"); edfButton = new QRadioButton("EDF (16-bit)"); bdfButton = new QRadioButton("BDF (24-bit)"); edfButton->setChecked(TRUE); vbox1 = new QVBoxLayout; vbox1->addWidget(edfButton); vbox1->addWidget(bdfButton); vbox1->addStretch(1); groupbox1->setLayout(vbox1); SeparatorLineEdit = new QLineEdit(ascii2edfDialog); SeparatorLineEdit->setGeometry(QRect(160, 20, 30, 21)); SeparatorLineEdit->setMaxLength(3); SeparatorLineEdit->setText("tab"); NumcolumnsSpinbox = new QSpinBox(ascii2edfDialog); NumcolumnsSpinbox->setGeometry(QRect(160, 50, 70, 22)); NumcolumnsSpinbox->setRange(1,256); NumcolumnsSpinbox->setValue(1); DatastartSpinbox = new QSpinBox(ascii2edfDialog); DatastartSpinbox->setGeometry(QRect(160, 80, 70, 22)); DatastartSpinbox->setRange(1,100); DatastartSpinbox->setValue(1); SamplefreqSpinbox = new QDoubleSpinBox(ascii2edfDialog); SamplefreqSpinbox->setGeometry(QRect(160, 110, 140, 22)); SamplefreqSpinbox->setDecimals(7); SamplefreqSpinbox->setRange(0.0000001,1000000.0); SamplefreqSpinbox->setSuffix(" Hz"); SamplefreqSpinbox->setValue(1.0); PatientnameLineEdit = new QLineEdit(ascii2edfDialog); PatientnameLineEdit->setGeometry(QRect(160, 140, 420, 21)); PatientnameLineEdit->setMaxLength(80); RecordingLineEdit = new QLineEdit(ascii2edfDialog); RecordingLineEdit->setGeometry(QRect(160, 170, 420, 21)); RecordingLineEdit->setMaxLength(80); StartDatetimeedit = new QDateTimeEdit(ascii2edfDialog); StartDatetimeedit->setGeometry(QRect(160, 200, 140, 22)); StartDatetimeedit->setDisplayFormat("dd/MM/yyyy hh:mm:ss"); StartDatetimeedit->setDateTime(QDateTime::currentDateTime()); autoPhysicalMaximumCheckbox = new QCheckBox(ascii2edfDialog); autoPhysicalMaximumCheckbox->setGeometry(QRect(560, 200, 20, 20)); autoPhysicalMaximumCheckbox->setTristate(FALSE); autoPhysicalMaximumCheckbox->setCheckState(Qt::Checked); SignalsTablewidget = new QTableWidget(ascii2edfDialog); SignalsTablewidget->setGeometry(QRect(160, 230, 420, 140)); SignalsTablewidget->setSelectionMode(QAbstractItemView::NoSelection); SignalsTablewidget->setColumnCount(5); SignalsTablewidget->setColumnWidth(0, 20); SignalsTablewidget->setColumnWidth(1, 120); SignalsTablewidget->setColumnWidth(2, 120); SignalsTablewidget->setColumnWidth(3, 120); SignalsTablewidget->setColumnWidth(4, 120); SignalsTablewidget->setRowCount(1); SignalsTablewidget->setRowHeight(0, 20); SignalsTablewidget->setCellWidget(0, 0, new QCheckBox); ((QCheckBox *)SignalsTablewidget->cellWidget(0, 0))->setCheckState(Qt::Checked); SignalsTablewidget->setCellWidget(0, 1, new QLineEdit); ((QLineEdit *)SignalsTablewidget->cellWidget(0, 1))->setMaxLength(16); SignalsTablewidget->setCellWidget(0, 2, new QLineEdit); ((QLineEdit *)SignalsTablewidget->cellWidget(0, 2))->setMaxLength(7); ((QLineEdit *)SignalsTablewidget->cellWidget(0, 2))->setEnabled(FALSE); SignalsTablewidget->setCellWidget(0, 3, new QLineEdit); ((QLineEdit *)SignalsTablewidget->cellWidget(0, 3))->setMaxLength(8); SignalsTablewidget->setCellWidget(0, 4, new QDoubleSpinBox); ((QDoubleSpinBox *)SignalsTablewidget->cellWidget(0, 4))->setDecimals(4); ((QDoubleSpinBox *)SignalsTablewidget->cellWidget(0, 4))->setRange(0.0001,1000000.0); ((QDoubleSpinBox *)SignalsTablewidget->cellWidget(0, 4))->setValue(1.0); QStringList horizontallabels; horizontallabels += ""; horizontallabels += "Label"; horizontallabels += "Physical maximum"; horizontallabels += "Physical dimension"; horizontallabels += "Multiplier"; SignalsTablewidget->setHorizontalHeaderLabels(horizontallabels); GoButton = new QPushButton(ascii2edfDialog); GoButton->setGeometry(QRect(20, 400, 75, 25)); GoButton->setText("Start"); CloseButton = new QPushButton(ascii2edfDialog); CloseButton->setGeometry(QRect(160, 400, 75, 25)); CloseButton->setText("Cancel"); SaveButton = new QPushButton(ascii2edfDialog); SaveButton->setGeometry(QRect(400, 400, 75, 25)); SaveButton->setText("Save"); LoadButton = new QPushButton(ascii2edfDialog); LoadButton->setGeometry(QRect(510, 400, 75, 25)); LoadButton->setText("Load"); columns = 1; edfsignals = 1; QObject::connect(NumcolumnsSpinbox, SIGNAL(valueChanged(int)), this, SLOT(numofcolumnschanged(int))); QObject::connect(GoButton, SIGNAL(clicked()), this, SLOT(gobuttonpressed())); QObject::connect(CloseButton, SIGNAL(clicked()), ascii2edfDialog, SLOT(close())); QObject::connect(SaveButton, SIGNAL(clicked()), this, SLOT(savebuttonpressed())); QObject::connect(LoadButton, SIGNAL(clicked()), this, SLOT(loadbuttonpressed())); QObject::connect(autoPhysicalMaximumCheckbox, SIGNAL(stateChanged(int)), this, SLOT(autoPhysicalMaximumCheckboxChanged(int))); ascii2edfDialog->exec(); } void UI_ASCII2EDFapp::autoPhysicalMaximumCheckboxChanged(int state) { int i; if(state == Qt::Checked) { autoPhysicalMaximum = 1; for(i=0; i< columns; i++) { ((QLineEdit *)SignalsTablewidget->cellWidget(i, 2))->setEnabled(FALSE); } } else { autoPhysicalMaximum = 0; for(i=0; i< columns; i++) { ((QLineEdit *)SignalsTablewidget->cellWidget(i, 2))->setEnabled(TRUE); } } } void UI_ASCII2EDFapp::numofcolumnschanged(int cnt) { int i; if(cnt>columns) { SignalsTablewidget->setRowCount(cnt); for(i=columns; isetRowHeight(i, 20); SignalsTablewidget->setCellWidget(i, 0, new QCheckBox); ((QCheckBox *)SignalsTablewidget->cellWidget(i, 0))->setCheckState(Qt::Checked); SignalsTablewidget->setCellWidget(i, 1, new QLineEdit); ((QLineEdit *)SignalsTablewidget->cellWidget(i, 1))->setMaxLength(16); SignalsTablewidget->setCellWidget(i, 2, new QLineEdit); ((QLineEdit *)SignalsTablewidget->cellWidget(i, 2))->setMaxLength(7); if(autoPhysicalMaximum) { ((QLineEdit *)SignalsTablewidget->cellWidget(i, 2))->setEnabled(FALSE); } else { ((QLineEdit *)SignalsTablewidget->cellWidget(i, 2))->setEnabled(TRUE); } SignalsTablewidget->setCellWidget(i, 3, new QLineEdit); ((QLineEdit *)SignalsTablewidget->cellWidget(i, 3))->setMaxLength(8); SignalsTablewidget->setCellWidget(i, 4, new QDoubleSpinBox); ((QDoubleSpinBox *)SignalsTablewidget->cellWidget(i, 4))->setDecimals(4); ((QDoubleSpinBox *)SignalsTablewidget->cellWidget(i, 4))->setRange(0.0001,1000000.0); ((QDoubleSpinBox *)SignalsTablewidget->cellWidget(i, 4))->setValue(1.0); edfsignals++; } } if(cnt=cnt; i--) { delete SignalsTablewidget->cellWidget(i, 0); delete SignalsTablewidget->cellWidget(i, 1); delete SignalsTablewidget->cellWidget(i, 2); delete SignalsTablewidget->cellWidget(i, 3); delete SignalsTablewidget->cellWidget(i, 4); SignalsTablewidget->removeRow(i); edfsignals--; } } columns = cnt; } void UI_ASCII2EDFapp::gobuttonpressed() { int i, j, k, p, column, column_end, headersize, temp, datarecords, str_start, line_nr, smpls_per_block=0, bufsize=0, edf_signal, len; char path[MAX_PATH_LENGTH], txt_string[ASCII_MAX_LINE_LEN], str[256], line[ASCII_MAX_LINE_LEN], *buf, scratchpad[128], outputfilename[MAX_PATH_LENGTH]; FILE *inputfile, *outputfile; ascii2edfDialog->setEnabled(FALSE); if(edfButton->isChecked() == TRUE) { edf_format = 1; } else { edf_format = 0; } if(check_input()) { ascii2edfDialog->setEnabled(TRUE); return; } if(!(strlen(PatientnameLineEdit->text().toLatin1().data()))) { QMessageBox messagewindow(QMessageBox::Critical, "Invalid input", "Please enter a subjectname."); messagewindow.exec(); ascii2edfDialog->setEnabled(TRUE); return; } if(!(strlen(RecordingLineEdit->text().toLatin1().data()))) { QMessageBox messagewindow(QMessageBox::Critical, "Invalid input", "Please enter a recording description."); messagewindow.exec(); ascii2edfDialog->setEnabled(TRUE); return; } strcpy(path, QFileDialog::getOpenFileName(0, "Open ASCII file", QString::fromLocal8Bit(recent_opendir), "ASCII files (*.txt *.TXT *.csv *.CSV)").toLocal8Bit().data()); if(!strcmp(path, "")) { ascii2edfDialog->setEnabled(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(); ascii2edfDialog->setEnabled(TRUE); return; } /********************** check file *************************/ rewind(inputfile); temp = 0; for(i=0; i<(startline-1);) { temp = fgetc(inputfile); if(temp==EOF) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "File does not contain enough lines."); messagewindow.exec(); fclose(inputfile); ascii2edfDialog->setEnabled(TRUE); return; } if(temp=='\n') { i++; } } headersize = ftello(inputfile); columns = NumcolumnsSpinbox->value(); column_end = 1; column = 0; for(i=0; i<(ASCII_MAX_LINE_LEN - 2); i++) { temp = fgetc(inputfile); if(temp==EOF) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "File does not contain enough lines."); messagewindow.exec(); fclose(inputfile); ascii2edfDialog->setEnabled(TRUE); return; } if(temp=='\r') { continue; } if(temp==separator) { if(!column_end) { column++; column_end = 1; } } else { if(temp=='\n') { if(!column_end) { column++; } if(column!=columns) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Number of columns does not match."); messagewindow.exec(); fclose(inputfile); ascii2edfDialog->setEnabled(TRUE); return; } break; } column_end = 0; } } if(i>ASCII_MAX_LINE_LEN) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Too many characters in a line."); messagewindow.exec(); fclose(inputfile); ascii2edfDialog->setEnabled(TRUE); return; } /***************** find highest physical maximums ***********************/ if(autoPhysicalMaximum) { QApplication::setOverrideCursor(Qt::WaitCursor); for(j=0; j<10; j++) qApp->processEvents(); for(i=0; isetEnabled(TRUE); return; } line_nr++; for(j=0; jprocessEvents(); continue; } i++; if(i>(ASCII_MAX_LINE_LEN - 2)) { QApplication::restoreOverrideCursor(); snprintf(txt_string, ASCII_MAX_LINE_LEN, "Error, line %i is too long.\n", line_nr); QMessageBox messagewindow(QMessageBox::Critical, "Error", txt_string); messagewindow.exec(); fclose(inputfile); ascii2edfDialog->setEnabled(TRUE); return; } } columns = NumcolumnsSpinbox->value(); edf_signal = 0; for(i=0; icellWidget(i, 4))->value(); if(physmax[edf_signal] > 9999999.0) { physmax[edf_signal] = 9999999.0; } if(edf_format) { sensitivity[edf_signal] = 32767.0 / physmax[edf_signal]; } else { sensitivity[edf_signal] = 8388607.0 / physmax[edf_signal]; } sensitivity[edf_signal++] *= ((QDoubleSpinBox *)SignalsTablewidget->cellWidget(i, 4))->value(); } } QApplication::restoreOverrideCursor(); } /***************** write header *****************************************/ outputfilename[0] = 0; if(recent_savedir[0]!=0) { strcpy(outputfilename, recent_savedir); strcat(outputfilename, "/"); } len = strlen(outputfilename); get_filename_from_path(outputfilename + len, path, MAX_PATH_LENGTH - len); remove_extension_from_filename(outputfilename); if(edf_format) { strcat(outputfilename, ".edf"); strcpy(outputfilename, QFileDialog::getSaveFileName(0, "Output file", QString::fromLocal8Bit(outputfilename), "EDF files (*.edf *.EDF)").toLocal8Bit().data()); } else { strcat(outputfilename, ".bdf"); strcpy(outputfilename, QFileDialog::getSaveFileName(0, "Output file", QString::fromLocal8Bit(outputfilename), "BDF files (*.bdf *.BDF)").toLocal8Bit().data()); } if(!strcmp(outputfilename, "")) { fclose(inputfile); ascii2edfDialog->setEnabled(TRUE); return; } get_directory_from_path(recent_savedir, outputfilename, MAX_PATH_LENGTH); outputfile = fopeno(outputfilename, "wb"); if(outputfile==NULL) { snprintf(txt_string, ASCII_MAX_LINE_LEN, "Can not open file %s for writing.", outputfilename); QMessageBox messagewindow(QMessageBox::Critical, "Error", txt_string); messagewindow.exec(); fclose(inputfile); ascii2edfDialog->setEnabled(TRUE); return; } if(edf_format) { fprintf(outputfile, "0 "); } else { fputc(255, outputfile); fprintf(outputfile, "BIOSEMI"); } p = snprintf(scratchpad, 128, "%s", PatientnameLineEdit->text().toLatin1().data()); for( ; p<80; p++) { scratchpad[p] = ' '; } latin1_to_ascii(scratchpad, 80); scratchpad[80] = 0; fprintf(outputfile, "%s", scratchpad); p = snprintf(scratchpad, 128, "%s", RecordingLineEdit->text().toLatin1().data()); for( ; p<80; p++) { scratchpad[p] = ' '; } latin1_to_ascii(scratchpad, 80); scratchpad[80] = 0; fprintf(outputfile, "%s", scratchpad); fprintf(outputfile, "%02i.%02i.%02i%02i.%02i.%02i", StartDatetimeedit->date().day(), StartDatetimeedit->date().month(), StartDatetimeedit->date().year() % 100, StartDatetimeedit->time().hour(), StartDatetimeedit->time().minute(), StartDatetimeedit->time().second()); fprintf(outputfile, "%-8i", 256 * edfsignals + 256); fprintf(outputfile, " "); fprintf(outputfile, "-1 "); if(samplefrequency<1.0) { datrecduration = 1.0 / samplefrequency; snprintf(str, 256, "%.8f", datrecduration); if(fwrite(str, 8, 1, outputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "A write error occurred."); messagewindow.exec(); fclose(inputfile); fclose(outputfile); ascii2edfDialog->setEnabled(TRUE); return; } } else { if(((int)samplefrequency)%10) { datrecduration = 1.0; fprintf(outputfile, "1 "); } else { datrecduration = 0.1; fprintf(outputfile, "0.1 "); } } fprintf(outputfile, "%-4i", edfsignals); for(i=0; icellWidget(i, 1))->text().toLatin1().data()); for(j=p; j<16; j++) { fputc(' ', outputfile); } } } for(i=0; i<(80*edfsignals); i++) { fputc(' ', outputfile); } for(i=0; icellWidget(i, 3))->text().toLatin1().data()); for(j=p; j<8; j++) { fputc(' ', outputfile); } } } edf_signal = 0; for(i=0; icellWidget(i, 2))->text().toLatin1().data()); for(j=p; j<7; j++) { fputc(' ', outputfile); } } } } edf_signal = 0; for(i=0; icellWidget(i, 2))->text().toLatin1().data()); for(j=p; j<8; j++) { fputc(' ', outputfile); } if(edf_format) { sensitivity[edf_signal] = 32767.0 / atof(((QLineEdit *)SignalsTablewidget->cellWidget(i, 2))->text().toLatin1().data()); } else { sensitivity[edf_signal] = 8388607.0 / atof(((QLineEdit *)SignalsTablewidget->cellWidget(i, 2))->text().toLatin1().data()); } sensitivity[edf_signal++] *= ((QDoubleSpinBox *)SignalsTablewidget->cellWidget(i, 4))->value(); } } } for(i=0; iprocessEvents(); if(edf_format) { bufsize = smpls_per_block * 2 * edfsignals; } else { bufsize = smpls_per_block * 3 * edfsignals; } buf = (char *)calloc(1, bufsize); if(buf==NULL) { QApplication::restoreOverrideCursor(); QMessageBox messagewindow(QMessageBox::Critical, "Error", "Malloc error (buf)"); messagewindow.exec(); fclose(inputfile); fclose(outputfile); ascii2edfDialog->setEnabled(TRUE); return; } fseeko(inputfile, (long long)headersize, SEEK_SET); i = 0; k = 0; column = 0; column_end = 1; datarecords = 0; str_start = 0; edf_signal = 0; line_nr = startline; while(1) { temp = fgetc(inputfile); if(temp==EOF) { break; } line[i] = temp; if(line[i]=='\r') { continue; } if(separator!=',') { if(line[i]==',') { line[i] = '.'; } } if(line[i]==separator) { if(!column_end) { if(column_enabled[column]) { value[edf_signal] = atof(line + str_start); edf_signal++; } column_end = 1; column++; } } else { if(line[i]!='\n') { if(column_end) { str_start = i; column_end = 0; } } } if(line[i]=='\n') { if(!column_end) { if(column_enabled[column]) { value[edf_signal] = atof(line + str_start); edf_signal++; } column++; column_end = 1; } if(column!=columns) { for(j=0; jsetEnabled(TRUE); return; } line_nr++; for(j=0; j32767) temp = 32767; if(temp<-32768) temp = -32768; *(((short *)buf) + k + (j * smpls_per_block)) = (short)temp; } else { if(temp>8388607) temp = 8388607; if(temp<-8388608) temp = -8388608; p = (k + (j * smpls_per_block)) * 3; buf[p++] = temp & 0xff; buf[p++] = (temp>>8) & 0xff; buf[p] = (temp>>16) & 0xff; } } k++; if(k>=smpls_per_block) { if(fwrite(buf, bufsize, 1, outputfile)!=1) { QApplication::restoreOverrideCursor(); QMessageBox messagewindow(QMessageBox::Critical, "Error", "Write error during conversion."); messagewindow.exec(); fclose(inputfile); fclose(outputfile); free(buf); ascii2edfDialog->setEnabled(TRUE); return; } datarecords++; k = 0; } str_start = 0; i = 0; column = 0; column_end = 1; edf_signal = 0; qApp->processEvents(); continue; } i++; if(i>(ASCII_MAX_LINE_LEN - 2)) { QApplication::restoreOverrideCursor(); snprintf(txt_string, ASCII_MAX_LINE_LEN, "Error, line %i is too long.\n", line_nr); QMessageBox messagewindow(QMessageBox::Critical, "Error", txt_string); messagewindow.exec(); fclose(inputfile); fclose(outputfile); free(buf); ascii2edfDialog->setEnabled(TRUE); return; } } QApplication::restoreOverrideCursor(); fseeko(outputfile, 236LL, SEEK_SET); fprintf(outputfile, "%-8i", datarecords); free(buf); if(fclose(outputfile)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred when closing outputfile."); messagewindow.exec(); fclose(inputfile); ascii2edfDialog->setEnabled(TRUE); return; } if(fclose(inputfile)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred when closing inputfile."); messagewindow.exec(); ascii2edfDialog->setEnabled(TRUE); return; } snprintf(txt_string, ASCII_MAX_LINE_LEN, "Done. EDF file is located at %s\n", outputfilename); QMessageBox messagewindow(QMessageBox::Information, "Ready", txt_string); messagewindow.setIconPixmap(QPixmap(":/images/ok.png")); messagewindow.exec(); ascii2edfDialog->setEnabled(TRUE); } void UI_ASCII2EDFapp::savebuttonpressed() { int i, j, len; char path[MAX_PATH_LENGTH], str[128]; FILE *outputfile; ascii2edfDialog->setEnabled(FALSE); if(check_input()) { ascii2edfDialog->setEnabled(TRUE); return; } path[0] = 0; if(recent_savedir[0]!=0) { strcpy(path, recent_savedir); strcat(path, "/"); } strcat(path, "ascii_to_edf.template"); strcpy(path, QFileDialog::getSaveFileName(0, "Save parameters", QString::fromLocal8Bit(path), "Template files (*.template *.TEMPLATE)").toLocal8Bit().data()); if(!strcmp(path, "")) { ascii2edfDialog->setEnabled(TRUE); return; } get_directory_from_path(recent_savedir, path, MAX_PATH_LENGTH); outputfile = fopeno(path, "wb"); if(outputfile==NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not open file for writing."); messagewindow.exec(); ascii2edfDialog->setEnabled(TRUE); return; } fprintf(outputfile, "\n<" PROGRAM_NAME "_ascii2edf_template>\n"); fprintf(outputfile, " %s\n", SeparatorLineEdit->text().toLatin1().data()); fprintf(outputfile, " %i\n", columns); fprintf(outputfile, " %i\n", startline); fprintf(outputfile, " %.10f\n", samplefrequency); fprintf(outputfile, " %i\n", autoPhysicalMaximum); if(edfButton->isChecked() == TRUE) { fprintf(outputfile, " 1\n"); } else { fprintf(outputfile, " 0\n"); } for(i=0; i\n"); if(((QCheckBox *)SignalsTablewidget->cellWidget(i, 0))->checkState()==Qt::Checked) { fprintf(outputfile, " 1\n"); } else { fprintf(outputfile, " 0\n"); } strcpy(str, ((QLineEdit *)SignalsTablewidget->cellWidget(i, 1))->text().toLatin1().data()); len = strlen(str); for(j=len-1; j>0; j--) { if(str[j]!=' ') break; } str[j+1] = 0; fprintf(outputfile, " \n", str); strcpy(str, ((QLineEdit *)SignalsTablewidget->cellWidget(i, 2))->text().toLatin1().data()); len = strlen(str); for(j=len-1; j>0; j--) { if(str[j]!=' ') break; } str[j+1] = 0; fprintf(outputfile, " %s\n", str); strcpy(str, ((QLineEdit *)SignalsTablewidget->cellWidget(i, 3))->text().toLatin1().data()); len = strlen(str); for(j=len-1; j>0; j--) { if(str[j]!=' ') break; } str[j+1] = 0; fprintf(outputfile, " %s\n", str); fprintf(outputfile, " %f\n", ((QDoubleSpinBox *)SignalsTablewidget->cellWidget(i, 4))->value()); fprintf(outputfile, " \n"); } fprintf(outputfile, "\n"); fclose(outputfile); ascii2edfDialog->setEnabled(TRUE); } void UI_ASCII2EDFapp::loadbuttonpressed() { int i, temp; char path[MAX_PATH_LENGTH], *content; double f_temp; struct xml_handle *xml_hdl; strcpy(path, QFileDialog::getOpenFileName(0, "Load parameters", QString::fromLocal8Bit(recent_opendir), "Template files (*.template *.TEMPLATE)").toLocal8Bit().data()); if(!strcmp(path, "")) { return; } get_directory_from_path(recent_opendir, path, MAX_PATH_LENGTH); xml_hdl = xml_get_handle(path); if(xml_hdl==NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not open file for reading."); messagewindow.exec(); return; } if(strcmp(xml_hdl->elementname, PROGRAM_NAME "_ascii2edf_template")) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There seems to be an error in this template."); messagewindow.exec(); xml_close(xml_hdl); return; } if(xml_goto_nth_element_inside(xml_hdl, "separator", 0)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There seems to be an error in this template."); messagewindow.exec(); xml_close(xml_hdl); return; } content = xml_get_content_of_element(xml_hdl); if(!strcmp(content, "tab")) { SeparatorLineEdit->setText("tab"); free(content); } else { if(strlen(content)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There seems to be an error in this template."); messagewindow.exec(); free(content); xml_close(xml_hdl); return; } else { if((content[0]<32)||(content[0]>126)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There seems to be an error in this template."); messagewindow.exec(); free(content); xml_close(xml_hdl); return; } SeparatorLineEdit->setText(content); free(content); } } xml_go_up(xml_hdl); if(xml_goto_nth_element_inside(xml_hdl, "columns", 0)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There seems to be an error in this template."); messagewindow.exec(); xml_close(xml_hdl); return; } content = xml_get_content_of_element(xml_hdl); temp = atoi(content); free(content); if((temp<1)||(temp>256)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There seems to be an error in this template."); messagewindow.exec(); xml_close(xml_hdl); return; } NumcolumnsSpinbox->setValue(temp); columns = temp; SignalsTablewidget->setRowCount(columns); xml_go_up(xml_hdl); if(xml_goto_nth_element_inside(xml_hdl, "startline", 0)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There seems to be an error in this template."); messagewindow.exec(); xml_close(xml_hdl); return; } content = xml_get_content_of_element(xml_hdl); temp = atoi(content); free(content); if((temp<1)||(temp>100)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There seems to be an error in this template."); messagewindow.exec(); xml_close(xml_hdl); return; } DatastartSpinbox->setValue(temp); xml_go_up(xml_hdl); if(xml_goto_nth_element_inside(xml_hdl, "samplefrequency", 0)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There seems to be an error in this template."); messagewindow.exec(); xml_close(xml_hdl); return; } content = xml_get_content_of_element(xml_hdl); f_temp = atof(content); free(content); if((f_temp<0.0000001)||(f_temp>1000000.0)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There seems to be an error in this template."); messagewindow.exec(); xml_close(xml_hdl); return; } SamplefreqSpinbox->setValue(f_temp); xml_go_up(xml_hdl); if(!(xml_goto_nth_element_inside(xml_hdl, "autophysicalmaximum", 0))) { content = xml_get_content_of_element(xml_hdl); autoPhysicalMaximum = atoi(content); free(content); if((autoPhysicalMaximum<0)||(autoPhysicalMaximum>1)) { autoPhysicalMaximum = 1; } if(autoPhysicalMaximum) { autoPhysicalMaximumCheckbox->setCheckState(Qt::Checked); } else { autoPhysicalMaximumCheckbox->setCheckState(Qt::Unchecked); } xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "edf_format", 0))) { content = xml_get_content_of_element(xml_hdl); edf_format = atoi(content); free(content); if((edf_format<0)||(edf_format>1)) { edf_format = 0; } if(edf_format) { edfButton->setChecked(TRUE); } else { bdfButton->setChecked(TRUE); } xml_go_up(xml_hdl); } for(i=0; icellWidget(i, 0))->setCheckState(Qt::Unchecked); } free(content); xml_go_up(xml_hdl); if(xml_goto_nth_element_inside(xml_hdl, "label", 0)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There seems to be an error in this template."); messagewindow.exec(); xml_close(xml_hdl); return; } content = xml_get_content_of_element(xml_hdl); ((QLineEdit *)SignalsTablewidget->cellWidget(i, 1))->setText(content); free(content); xml_go_up(xml_hdl); if(xml_goto_nth_element_inside(xml_hdl, "physical_maximum", 0)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There seems to be an error in this template."); messagewindow.exec(); xml_close(xml_hdl); return; } content = xml_get_content_of_element(xml_hdl); ((QLineEdit *)SignalsTablewidget->cellWidget(i, 2))->setText(content); free(content); xml_go_up(xml_hdl); if(xml_goto_nth_element_inside(xml_hdl, "physical_dimension", 0)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There seems to be an error in this template."); messagewindow.exec(); xml_close(xml_hdl); return; } content = xml_get_content_of_element(xml_hdl); ((QLineEdit *)SignalsTablewidget->cellWidget(i, 3))->setText(content); free(content); xml_go_up(xml_hdl); if(xml_goto_nth_element_inside(xml_hdl, "multiplier", 0)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There seems to be an error in this template."); messagewindow.exec(); xml_close(xml_hdl); return; } content = xml_get_content_of_element(xml_hdl); ((QDoubleSpinBox *)SignalsTablewidget->cellWidget(i, 4))->setValue(atof(content)); free(content); xml_go_up(xml_hdl); xml_go_up(xml_hdl); } xml_close(xml_hdl); } int UI_ASCII2EDFapp::check_input(void) { int i, j, k, len, dot; char str[128], big_str[ASCII_MAX_LINE_LEN]; const char *columnname[]={"", "Label", "Physical maximum", "Physical dimension"}; strcpy(str, SeparatorLineEdit->text().toLatin1().data()); if(!strcmp(str, "tab")) { separator = '\t'; } else { if(strlen(str)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Invalid input", "Separator must be one character or tab."); messagewindow.exec(); return(1); } if((str[0]<32)||(str[0]>126)) { QMessageBox messagewindow(QMessageBox::Critical, "Invalid input", "Separator character is not a valid ASCII character."); messagewindow.exec(); return(1); } if(str[0]=='.') { QMessageBox messagewindow(QMessageBox::Critical, "Invalid input", "Separator character can not be a dot."); messagewindow.exec(); return(1); } if((str[0]>47)&&(str[0]<58)) { QMessageBox messagewindow(QMessageBox::Critical, "Invalid input", "Separator character can not be a number."); messagewindow.exec(); return(1); } separator = str[0]; } startline = DatastartSpinbox->value(); samplefrequency = SamplefreqSpinbox->value(); if(samplefrequency>=1.0) { if(samplefrequency>((double)((int)samplefrequency))) { QMessageBox messagewindow(QMessageBox::Critical, "Invalid input", "Only samplefrequencies below 1 Hz can have a decimal fraction."); messagewindow.exec(); return(1); } } edfsignals = 0; for(i=0; icellWidget(i, 0))->checkState()==Qt::Checked) { for(j=1; j<4; j++) { if((j == 2) && autoPhysicalMaximum) { continue; } dot = 0; strcpy(str, ((QLineEdit *)SignalsTablewidget->cellWidget(i, j))->text().toLatin1().data()); len = strlen(str); if(!len) { snprintf(big_str, ASCII_MAX_LINE_LEN, "%s field of row %i is empty.", columnname[j], i + 1); QMessageBox messagewindow(QMessageBox::Critical, "Invalid input", big_str); messagewindow.exec(); return(1); } for(k=0; k126)) { snprintf(big_str, ASCII_MAX_LINE_LEN, "Character %i in %s field of row %i is not a valid ASCII character.", k + 1, columnname[j], i + 1); QMessageBox messagewindow(QMessageBox::Critical, "Invalid input", big_str); messagewindow.exec(); return(1); } if(str[k]==' ') { if(k==0) { snprintf(big_str, ASCII_MAX_LINE_LEN, "Text in %s field of row %i is not valid.\nField must not be empty and left-aligned (no spaces in front of the text).", columnname[j], i + 1); QMessageBox messagewindow(QMessageBox::Critical, "Invalid input", big_str); messagewindow.exec(); return(1); } } if(j==2) { if(str[len-1]=='.') { snprintf(big_str, ASCII_MAX_LINE_LEN, "Text in %s field of row %i is not valid.\n" "Last character can not be a dot.", columnname[j], i + 1); QMessageBox messagewindow(QMessageBox::Critical, "Invalid input", big_str); messagewindow.exec(); return(1); } if((str[k]<48)||(str[k]>57)) { if(str[k]=='.') { if(dot) { snprintf(big_str, ASCII_MAX_LINE_LEN, "Text in %s field of row %i is not valid.\n" "Only one dot is allowed as a decimal separator.", columnname[j], i + 1); QMessageBox messagewindow(QMessageBox::Critical, "Invalid input", big_str); messagewindow.exec(); return(1); } else { if(k==0) { snprintf(big_str, ASCII_MAX_LINE_LEN, "Text in %s field of row %i is not valid.\n" "First character can not be a dot.", columnname[j], i + 1); QMessageBox messagewindow(QMessageBox::Critical, "Invalid input", big_str); messagewindow.exec(); return(1); } dot = 1; } } else { snprintf(big_str, ASCII_MAX_LINE_LEN, "Text in %s field of row %i is not valid.\n" "Field must contain a number and no spaces.", columnname[j], i + 1); QMessageBox messagewindow(QMessageBox::Critical, "Invalid input", big_str); messagewindow.exec(); return(1); } } } } if(j==2) { if(atof(str)<1.0) { snprintf(big_str, ASCII_MAX_LINE_LEN, "Value in %s field of row %i is not valid.\n" "Value must be 1 or more.", columnname[j], i + 1); QMessageBox messagewindow(QMessageBox::Critical, "Invalid input", big_str); messagewindow.exec(); return(1); } } } edfsignals++; column_enabled[i] = 1; } else { column_enabled[i] = 0; } } if(edfsignals<1) { QMessageBox messagewindow(QMessageBox::Critical, "Invalid input", "At least one row needs to be checked."); messagewindow.exec(); return(1); } return(0); } edfbrowser_153_source/PaxHeaders.2978/edf_annot_list.h0000644000175000001440000000013212251654530021310 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/edf_annot_list.h0000644000175000001440000000413612251654530021045 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef EDFPLUS_ANNOT_LIST_H #define EDFPLUS_ANNOT_LIST_H #include #include #include "global.h" #ifdef __cplusplus extern "C" { #endif void edfplus_annotation_add_item(struct annotationblock **, struct annotationblock *); void edfplus_annotation_add_copy(struct annotationblock **, struct annotationblock *); int edfplus_annotation_count(struct annotationblock **); void edfplus_annotation_delete(struct annotationblock **, int); void edfplus_annotation_delete_list(struct annotationblock **); struct annotationblock * edfplus_annotation_item(struct annotationblock **, int); void edfplus_annotation_sort(struct annotationblock **); struct annotationblock * edfplus_annotation_copy_list(struct annotationblock **); int get_tal_timestamp_digit_cnt(struct edfhdrblock *); int get_tal_timestamp_decimal_cnt(struct edfhdrblock *); int get_max_annotation_strlen(struct annotationblock **); #ifdef __cplusplus } /* extern "C" */ #endif #endif edfbrowser_153_source/PaxHeaders.2978/active_file_chooser.h0000644000175000001440000000012712251654530022320 xustar000000000000000029 mtime=1386699096.46603258 29 atime=1386699096.46603258 29 ctime=1386699096.46603258 edfbrowser_153_source/active_file_chooser.h0000644000175000001440000000335312251654530022051 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef ACTIVEFILESAVERFORM1_H #define ACTIVEFILESAVERFORM1_H #include #include #include #include #include #include #include "global.h" #include "mainwindow.h" class UI_Mainwindow; class UI_activeFileChooserWindow : public QObject { Q_OBJECT public: UI_activeFileChooserWindow(int *, QWidget *); private: QDialog *chooserDialog; QPushButton *okButton, *cancelButton; QListWidget *filelist; int *file_num; UI_Mainwindow *mainwindow; private slots: void okButtonClicked(); }; #endif edfbrowser_153_source/PaxHeaders.2978/averager_dialog.h0000644000175000001440000000012712251654530021437 xustar000000000000000029 mtime=1386699096.46603258 29 atime=1386699096.46603258 29 ctime=1386699096.46603258 edfbrowser_153_source/averager_dialog.h0000644000175000001440000000472312251654530021172 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef AVERAGER_FORM1_H #define AVERAGER_FORM1_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "mainwindow.h" #include "edf_annot_list.h" #include "averager_curve_wnd.h" #include "utils.h" class UI_Mainwindow; class UI_AveragerWindow : public QObject { Q_OBJECT public: UI_AveragerWindow(QWidget *, int); ~UI_AveragerWindow(); UI_Mainwindow *mainwindow; private: QDialog *averager_dialog; QLabel *annotLabel, *annotNameLabel, *signalLabel, *ratioLabel, *bufsizeLabel, *time1Label, *time2Label; QPushButton *CloseButton, *StartButton; QListWidget *list; QComboBox *ratioBox; QTimeEdit *timeEdit1, *timeEdit2; QTime time1, time2; QDoubleSpinBox *avg_periodspinbox; char annot_str[MAX_ANNOTATION_LEN + 1]; int signal_nr; double *avgbuf; void process_avg(struct signalcompblock *); private slots: void startButtonClicked(); }; #endif // AVERAGER_FORM1_H edfbrowser_153_source/PaxHeaders.2978/images0000644000175000001440000000013212251654530017337 xustar000000000000000030 mtime=1386699096.461032606 30 atime=1386699096.461032606 30 ctime=1386699096.461032606 edfbrowser_153_source/images/0000755000175000001440000000000012251654530017145 5ustar00novarausers00000000000000edfbrowser_153_source/images/PaxHeaders.2978/edf.ico0000644000175000001440000000013212251654530020646 xustar000000000000000030 mtime=1386699096.461032606 30 atime=1386699096.461032606 30 ctime=1386699096.461032606 edfbrowser_153_source/images/edf.ico0000644000175000001440000000727612251654530020413 0ustar00novarausers0000000000000000¨(0` XXX+ƒÿedfbrowser_153_source/images/PaxHeaders.2978/edf.png0000644000175000001440000000013212251654530020660 xustar000000000000000030 mtime=1386699096.461032606 30 atime=1386699096.461032606 30 ctime=1386699096.461032606 edfbrowser_153_source/images/edf.png0000644000175000001440000000124112251654530020407 0ustar00novarausers00000000000000‰PNG  IHDR00Wù‡ pHYs  šœ†zTXtCommentxœsI-Î.É/Ð-άJMQÈLÎÏã²E\\Éš F& ^‰Ù¥I êY™¹¹‰Éê Á%©™y©E: \%%Vúú ½ÜÒâÌäŒÄœ½ä*.®ä¢ÔÄ’Ô…òÌ’ …’ŒTwOߘ–òòr½ôÌܽü¢tè,>#þÝèÁIDAThíZKnƒ0}X‘…rŽî¢ž±B½KÓMQ¯R±Bœ¥JWQÏX@•‹ÝŒÁøƒKÄÛâ™y3oüAI Ø00¼žbÇa…ä|‹„+v±q ¦å•üqžçx?}ØË§òŽsŽöùAyv|û"ídYökÇ$ƘÆÉ8æœ+„ÒòŠ´¼Þ˜³ã RBmÛ.6$º<ºE´÷ÙPU*i\…•n›¦Á±Ç>õèš8M GvN}ÙÑ”Pß÷^„I ëºÅ†ÄÒëS& %Ä9G]×`•JDë”>¡ö5öÃ\Dìbc' O’[eýö…ûðS…9ýG™W Tð®vº*PWEð‘”Ù „ Þ‡Ýrþ:1éÈvmmŠ9Ú „ʼȱÑ_%N%Æ´ Ô§í¥^GB8³!é2O“÷̶GæV@qml0üÒìOe]†U¦4K½3 ^Ì˺Œ g!—åÖ4pošÚ3B®jÖ0ÉòûHðãth›¿8õÀZ:ŸÂæ+°ˆ}bõR˜$v ÅÆæ $Øøßm¾8Ô»•‘ÉÔIEND®B`‚edfbrowser_153_source/images/PaxHeaders.2978/ok.png0000644000175000001440000000013212251654530020533 xustar000000000000000030 mtime=1386699096.461032606 30 atime=1386699096.461032606 30 ctime=1386699096.461032606 edfbrowser_153_source/images/ok.png0000644000175000001440000000475312251654530020275 0ustar00novarausers00000000000000‰PNG  IHDR00Wù‡tEXtSoftwareAdobe ImageReadyqÉe< IDATxÚìZ[lGþfwÏÅ>Çvl'q“¦IêVMšD¡Ê-•¨ } q“*Ê @êˆ"ñ„Bž ¥žR¤Š6…B…ˆT*MÛÈ…¤IHÇI|͉ÏmÏewg˜ëîì9§¶)¤¬5™=»³3ÿ÷ßæÿÿ aŒáÿù"7Üð_ð _IÍ×£™‹õhøþ­?þ·ÖwÞ&èy2ºeuËY÷¿ÍX‡3€üÇ$°ë{;qçm“õVýOµº¿¿\ñsQ½#ª1rò¯üQh¿7t¯àÇ޿k¹\›ºybcvç¶ l†ëºœåü¶‹ž¨žÿ9DõJ,º'b1£C,î)cªÿ2Ó'c®—«˜](áÕœcãƒ#?zñ˯<Æ·Œê­ À~~`i÷ä-ã“Û·Xú¢DKÂÞ3Ž£AH¢5Ž©%É„KOPÌÐħðý6ž;rœù/úw;|ùŒñVc¥Zß±u4bhÔÚ¢j I´Cˆ¨gª%%ÉeM$å ’g®ÇçË:( çÏe°cëM¤ðÙü£À#|š€7jh\ÀØÈŸ8â,k”ÛÝDwÜ’¨!Z^± %*b¸LøÜDôLŒTÏù‚œI aò9ä F‡ Ⱥ™;…iðV5RX@Æó$÷Àvï:Jm\þ›èÞ€0¤´˜@rZ0†P8¢×¤n %t¨¼Òë‹5=.þ2¯i^Í>´š$ÄÇDO,0F…, 6áF…ñ„PÞ … FÏ ñ^¯/¿£r€ÛéúW W“4êaˆKR0"°ADBu4ñU’е– Ñû ÓFï §·ñVóÇŒiÏã¤[/ Hb ÐjÄ”źï%Nâ•c%qs¸`e ý`R’jË&ŠËBMRD»¶D53ª”’€ö2ó—Kp2.²¼œï ’Å8¢šä½[g(‘lR’0M¤ ‹› òøf—qÝžý¥³ópkì:ˆ°¡å)5Tó'nÙ §Ö§Bf75®Òx"nFÖ{Ë iâjÓ¤xð=ŸÁþíïÅûêà…ÓOáÂÒ) ŽäÕüBÙ!±Ø¬•›Uhú»DíYlFm: [´Ø,>{rÛGvc϶òÙæÂ6<|Ï×1]}Ï\ü "n‚xÂŒ#°6DŽÉñBCÚ éЉ2»­‹:q¡6¡Nv¿xe¬Mð±{æÏ2©U¶v&Þ+µìõ‰Ð—ì°Œ¦­Áòó¤„í™ä³ÄˆË×ê8°ã>LlØÖµÎѹ§S!H¼Ðd;.Y‡ Ä¢´U)Ž>-$Þì´GÒÞù3W¶‡û÷~BÙ†uÍ5.àÍêÉ8¾Š×ÐÀÅ}È7‚ZTú–@ƒú(·—1èù@3Çʽ#v 8 (Ÿ‚÷ïý ¹áÔü ðòµßÆó˜¹Å]›¿«‡54Ã:Êá5ÍVÿÚQC™ 8W;6€b¶(ÛSäéT>^ìÂéY yã`yccCß<sô©KüÛ1¸õ¾®ù/Ö§°Ôº"ǶYˆjTE­]“­Ô°9·ïz764®áÕæ1¬Ë MöàŽâ~”›K˜kÍ ,`6œF!Ä`f™®VJøÒÁ/`rón»øk\ånqp9˜¦âãw=Ä÷lj^?*ãùÅ_`©½?ðQêÈÓ"FÝM˜ÞÍ¥>Št¹9¥×ÞÒÛ¬ àù¹§¤w7cb` vöq©àƒs‰^Ç™×ßä^ävÜ}˽rüGw}g˯á™+ã/ÁÞ⽘œØÓ5ï±ëÏ¢”0D†±%·ƒ¹"jD¹]Æ©êóJ5½$¡à.”­k#_-¶æQ à6ĦEËæ$Vàk|75þŽ‘»ñèÈ“øKñ÷¸}l—Û\j_Ɖåpµ©ð9§ƒi´Â"¶G<|a4KyB_°^œµ‘ŸBL€pÂËaáHSµ?÷üòàö`Sqk×óÃK?ÅB0kÁjamë°Yo©Â‹Ê’e±þc!ó± Ä’{‘©‰¤¤°1‡CW€ïüósx½v¼çNn_güW0U9®RHªSJ}ßk˯W6çõB"Ñ‹ úgfýi<9ý-<1óM̵§{NÓânùÙ¹Çåx»fH)P;ñI"8q¿`I)DL,ˆ•¾^m04R‘–fý½ü7¿áƒãŸÄƒ›>¬“ß½´üÌøçÁ‘"šÒ4j@Z]K“z£«H€t$fÖäöâ‘Õh¨ŒðÈÂÓxì̧q¬tXα,âðìÏÔ{{¼„ÑD±=˜`¤Sל‘- -©>©Ê'Uƒ¸g’!°¨’R-ªàÐ¥âèâs˜Ü‹z«'ô]R ¶ ÒNGÅC&¹Y_> ƒ*ÊhRéQ²Ü!i€‰­§«çdÓɹ¥óiI¦ÀˆÔ“ÅØ:óÛHK ŠVÚ]nSÄk#WÜW_'P»*a;‚N ¤ZÏw*ßì€.dÄ3ý¡ÖÞ “~C<³£I¦Ä…!í’a¹án›ŠË(Æb²6?Ç:itߦÓ͵Dò‘Ñ^×!!ÿ«×šÜø¯7¬~ýK€úˆ#¸Ø"ÁIEND®B`‚edfbrowser_153_source/images/PaxHeaders.2978/splash.png0000644000175000001440000000013212251654530021414 xustar000000000000000030 mtime=1386699096.461032606 30 atime=1386699096.461032606 30 ctime=1386699096.461032606 edfbrowser_153_source/images/splash.png0000644000175000001440000002207712251654530021155 0ustar00novarausers00000000000000‰PNG  IHDR©æº ‹bKGDÿÿÿ ½§“ pHYs  šœtIMEÝ ,;¬ ïJ!iTXtCommentCreated with The GIMPm°— IDATxíxÕµÇ,Y–«Üd˽w¦’€M30Å4‡ÐBMáQòòy”!äá<†BL 1 -˜^ ¦Øqï–{“«lYzç¬4ÒììjW¹»÷w¾OìÎ;³çþÎ0ß{ÏÜÉ©¼eD¥`€  4sÐ'\‚ Ä R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,DÊÙÐà  R\€ à,þäæ‹äé_«"­uNʨ÷þUÃ|-Ú$¢¶y«3îyä»";J÷×·¤>¾Õ÷\Ôƒ¾Vô¤¾VÜžÿØî"e[D6,Y¦ÉÓŸyþç"÷Œyç!‘ÊŠD@{‹Œ»)±œ@À ˆ”av¼‘e›EÞ¸Kä‰ìÜ–èìP± 0q/%€@@¤²8¸×´ÅŠ<ùC‘Ý»]?âªÄ2J ¬'€He}ˆ3¬K?yíÎD§»é3*±œ@ « RYÞ m܇ú¬ÔÊY‰Îïsrb%€@V@¤²:¼ܸ©¿Mt~Б}胼!€Hyê k¨-‘dëû…­e¡H÷4ë †ëóÈxˆTƇ0KP©kùÍ;±qÝ÷N,£ÈZˆTÖ†6 ¶ü³ÄFt–XF  µ©¬ m4l­¾Æ#j…=¢%lCYL€e‘25¸MõÞ$—–²•)¢Ö®8Z’~»±X¹Ä&}«©¬ @O*+˜¥Ø©/GŒZAÛh Û€@@¤²8¸ß´dK$Ù 1@Àˆ”7¡ÎÀ†&[)—ê Œ$.C Á©£ãÀ&'×"ñ'Êu%u ð†ÿ,ÍÔPû0‰Ÿß*1:»¶'–¥+ñU:ì‡@† '•¡óÂí6E‰Íܺ>±Œ@ k RYÚ,hXûž‰Ø¼*±Œ@ k RYÚ,hX×!‰X» ±Œ@ k RYÚ,hXŸ±*É+<kQd D*K™uÍ(h'Òsdb³–LK,£ÈZˆTÖ†6ö÷ "¹Íã±~‰H²¥’âk±dD*‹‚™5Mi¦OFtnbsf¾”XF  Õ©¬o†6Ϊ}dµóÊ ‘éÏehƒph(Dª¡ä8®iØK Çü8ñÜsÞÙ¸,±œ@ « °âDV‡7Ã×g”È©wŠäåÇ;^¡oéýç½ñeº•sýŒ¸²Ê[FÄm³d>D*óc˜ù-°wDÙߨ³Uy’tî?øƒÈš¹™ßNZì1Dj‘q@ƒ XBDó‘VD »‹ éwÈÀÑ"Ír“ŸvñG"oÜ|¥€@Ö@¤25Äõ¶ÙºÚ¿§‹²6…?–rþÌ•"åuyI9 å’Œ­dy‹i^fX6]ä±sD¶oÊ ñhô¤š+'m0{_ÔGOh¢Ä="É^zØàs  ‰©LŒZ6ú¼e­ÈÌ—EÞŸ$Rº2› @¤CHÀzF;·‰”mÙ¦ï…Z;_³öôφö–~ª'­là‰9 ÈVˆT&DvO“šºM®ùn¯úöú‚-òÀGä½%ÛdõÖÝÒ¹U® +j!ㇷ“sFJÛudVŸ'ÙóWóÖ•É•/®Ôs«Àª îœ/Çn+·ŽíZ}TüGùîJyvf©<ýå&ùhùY±YZ­¸Mžس¥œ6¢œ>¢PòrsâÔ­§¾Ø$žZVS~°Öïýk¶“})+¯¢ÛfËæÒ\gšW_3TÚ·LÝÎîŸ/ÓJvÔœî© =åô½ k¶§¯Ø.ú|“¼«g¯Ý)wì–¼f9ÒµužŒèÚBÆh#gíS(Eº]_«¬¬”¿ÏÞ"Ö6~°t›,ß\.å•RÔ*Oöí^ §hŒÎúF¡X#RXcÄ(ÅéÙåú_]9+HFÀ„áG[!¿Ÿ¶!n·ÝíïU˜[ß\#÷ë&'ëͰ¾f3ú¡E²bKm–ág+ˤWadÜ꾯7ßïÿeyìÆý¥¥å²tæfù‹þÝüÆùé=c¢®wÜà6R—#;Ê«z–,Û.+Õ‡â¶ÉÏŽ}yî–˜@Ù÷]º‚Ôsÿ*•ó÷ÓTÿ:lÙ¦]qÕRï8]³íz‚‹ÿZ"O¨@EÍe±k/ÎÙ"×¾²J®ÝY®S$ÍTÀRÙ¬5erÎ3Ëäã0õí =ŸÓ¸<2¾»©"X_ÛÓÕ÷¼Ôû÷HýÏ•¿xz¸Ho¬QŠ\¢buꟗÊãÓ7FwÕ¹}É”’8 *Nõ:‚²)*c^”T ‚:Áç,íŒ~x¡ücîæ (öÙF{zßT{ƒ6©úÛìø:qè†õÚÂöÔñÛá}ö}ʬøýǪ0¶Îo&*Bã_’T ¢ç°mÒ__#?|~E²Ý5e&Ü?° ©@ÕTªþ²Dð˜ÇËŸ>kšEm· Гr;>x·«žþšË¯tîèmtxJäíÅÛä篬–é+«†¶ô>ë)Ø£¥ ÕaÀtfÃS}Û7—Oê.cú¶ºIŸl”“†Uõ<‚ãg¬Ú!gê0ÝNíÑ6²¸@~yT9¤O+±~Æ[1_VÉç«ÊbUì&úŸ—É´Kûëb­/6ø×Õ Óý~ñƒÓÆ}îÒß{~Vm]Ûùšy®ßV.u-™ÙùÂf¿gv߇ëåõ…UCš¶Ý¾ YÌÚìÑ®¹ìVx3µGô¿ï¯—G?­ûÇÁÙ:”:ºok;,ά—sâ—Ȧ2íâUÛ‰CÛÊUßê$ûë_³œ™±z‡üîà ±s=Cxþs%1&hœÒY}c”î<ìw=)÷b‚G_€‰Â´KÈ„½ ¥ƒÎÉØüÓ±zƒ}ÿýäˆ~µ7Ð2½ ^ñBêýnäë¼Ñ?Îí#cUôòUõúvÈ—›Žì’0·u¹žo{õ{x¿V±ß=~H[),È•vúgß?Ðù¥Ñ*ZmÑy¤Ët˜2l'h½¡ùª×t¨r«ÖKf¯ÎߢóEUû‚·ª!¿x! ŽÝ¤sKÿ ‘ -ŽÓß3{82Túä=岃:ÅÚÜ\ý±¹¢ýº·”I§ôKŒN|Pç“ÙO^Z%k¶éú‹ÕöKe7å¬Þr˜ÆÃâc=¸Q=[É#zÎI§èJ$Õfbÿ£¿•›)?룔'a§“)'ÂS !`7õÉ:ùŸ,a …ŠËOï!mõ†Ø+ó·ÊܵU=š ,Ùç©:5$MË’ ÞX¨™‹Õf¿óÄé=Å~7jv£·}­›’"±ù²OK¶×T5A;°VT­ÇeóNÉìÙµCwgjÒA`“59!™½8gslÞ*ØwŒŠoL2su<Ã’ôŒ‚ãþëÐÎÁרgT.\´a§LÖä‘ÀŽÐZþû°¢`3áó¼};Èw÷®/´¤“·Õöì¨.¨OŒê:–r· $þä¶¿x: œ±W»¸!³hÅnšx¾‰Û°ÒÓ¡|´~°ž Ê¢Ÿa¡°}ö;ö{uYOMºûbõ¢¾Ø7lÑy$ÛgÉ"Sª‡ú¬7q‹öR{C{Kk·Ö&{åáaD+ †úì{«HVÝ“uÕµ¥­<ü•ülˆÇÙÓ_–Š ¯vÅ7;_ëüŒ&|<šLv`}b”ì8ÊÜ'€H¹#<¬'“‡ÅßÔ“v¼&„íM¯NgûvÓEqÓØ»Kj{AV5ú;É·!½°YªwØNÒö„5ã³9¡°½©½ŒµÕCi‡êbÿŽù2¼º×§YéšEXÛ˲ãvjá?B=26› ̆àÂfY~h¦âk:¤hs_{jSÇ÷‚î•~~é§ ›%]¤³úÄ(Ý9Øï&䳪núŠWHI`d=Äd¯®ñ7ÀÕ ©NÜ[“&ÒÙ}Ž*l{ëÜX:‹Ö™»N—„ ™Í©Ñ¿µ¼<¯êF¿nûn±$1!!y&Ô´Ôu3;Æ’ÌžÒžÌ%Ö&\XRDi(a¬¿ÙÐb`7^$/©ˆÉ¦K“4AÂþló(­‚Šš%RtÑg¾ÒYtø°“>˵§6}<—dÇ×'FÉŽ£Ì}ô¤ÜÖ“@—Öµ7Ûº)ŠÔY¯7þtÖ&4UWÝ 7ì/ÒˆÓY´ÎºPrApìiúÀoØ‚¡=+³tñçB=¥cUõˆ±²:– ±:ô|W]Y}V×Ì’"žÖy½v-o ö ° ½] YwÝnŸ-‡þ~¡ÜóÞ:Y:ÕYjÿ›j_m­Ôß64RŒRÿ {]%x%ºê)~A è|J²êÑ:;lL,å¦yHÕ/ eõÙvËð8$±h{P6j'kš»ŽÈÕ˜=‡ØÛ:<¸JWÔ0³ùa]ªRØמV”a=¡à*[í!œªn.ÚbÔNÔ²ÙW ”ŸÒIW—H.¶æªýþº G¯‰³åGÏ—È–²DÁg;F§¾Ûõ‘Ô'Fõý=ê¹E }Ý-ñu°´ò–i%šÆmCja6·c¿˜­Ú`妲¨/QѲc;ë’Cc4Ã.xviÁ†]ò¥>eÖÏèP^`džþµìA[­!$[féÒQuy¦í±g¼‚cŽìß&–¦l‡?mu‹Û)–Ûôy³©‹¶é3[¥ò‚>P<_?j–î~¿¦ŸÛÊS/êK)êØ2JÁС••^7´&“0¨Ã'R '•Šû2Š@tÈ-™óÑá§Nõ–KvžhYt1ü\P´n°õÅÖLf§iÖbØ^Ò¥ƒÌþZ…"XÒ(¨7nHm‚ÈTÇ2Ñ´^Ã=ox_ðÝz(‡ë×ÝÇw“yW–¹W”{Ç‹¥’G³ë?Y±CnùçšàÐØg´MKu5 {B‘ÚZÔušÀœz<ó¬:4ddqúl³ nªÏÁª†Ú‚:ŸW¯nl'ûü"’´Ñ_Sº“™-ºî ¾¥s›uhmáÆª¾=fÉa³Ä†`”ІækÝWæÕŠ” Œ %î© ÔvÚý/¿¯,úÉ`92ò»Ñg³uŠoÓ‡ÚÛ °'©=¡E]§ ØsAé,úŒÐ·z7ŽHEÏc ¥¦³ô¡Ú°Õ•žÝU³èé]»BÅ;šîΚ³¥šZE’;ºëFá´ìéÚ˱á¾Àì!ÝNI–Lê­óK¶ÂxðWRZwÏÇ–Izü´Á)cŸË#õ¿òÛ*ócq±©pØ•YúxƒlL‘ f=­ðC·6tF’EbÒjëí„Í^q‘êoû¢½ŽðóJásÙ÷ðМe$†SÏmÙ§dfK0öÈ'bëáÛ§G†ƒòèsRÑ笂zÁg®®»¶¨ð…¶z&ÞŸ„VÖ|·¹¯@$íó¤'–»øô"åaгµÉ–évž>xšì¡S¯ “—Å%7œ­ïBªÏ³>õᵯ¦n[&0[ïœg–kÖ_bö •Ù¾­»j-ìQõª=>8Oði"–ƒðâ®á”ó ¾}†ç¥^Õ% ³lA{·V2;wßöqÅ6Ç´xcÝÏ)ÝñÎÚ¸úÑá?ã.³¡G[„×^=’Ìì"—j¦`Ø.¿F`xß³Ÿ"•ý1ö¦…v󵌶Ã^›)Õ…TMœ,»m}Á_x>ªGÛ<™xL×Fesï¸n±÷@'µŒ¼ƒXËŠ3_léEí%XY­gum×ûOì–ôÓ†ÖÂÃA’È]ñ=¼zzø`[å=H!¯•CÑ•Ê[Õù¢Â£4+0,¶öÒÈQ¿[ ¿ý`}L¬l¦m*ÀéÜ’­DqûÛëj~ÒøÿôÎ5ÛÁã¤Ä[Ù}hy¿ß.ëùZòˆÓ*îû`Ø‹í[ÙÊß©~þ+(ãÓ/¤ ûï¬ní­úJŒkô•ï.Ý.Gëûˆê²úú‰¿|¯W¯±¨ë¸tå–þÄi=õ­ºKõm³UµMÇék*ê2r´cFvK?7fCgïiÛÂV×PŸÕÉÑ¡8Ëú³Õ"Â}@8¼Ï¾Û ç‡èƒºöJ3ªËþ¾Bÿb›uþç7ÇË>IVý°×¡LžÐKN}riMOÖ^rx±¾§K¦Ôy:Ù[ßþû¸²Áü&@OÊïøgUëmUîkôOÿA_§íSÜ"ö,½¢)ì’×Ïï+öN«t6¬(_Þ¼°¯Ø1õ±èüŽ~>*Ù9‚Wpû,Kð”áµsUAyø³ŸfÚóN߬Ç:{vœõÖ&ë+=.?¸îÅcm~lêE}ÅÚ\³WÈ¿­>4ÖslõùMê¸I€ž”›qÁ«°žÃmGwÕÞC¹W‡§Þ«^‘ÁžÕÙG×Òû®¾cê,‡jêÕ Õ̹ýÇ@}EEi,Qcš& ذ–½Ü¯›3ŽÒù'Kد)àé^¹ÆÐ»}¾Ø£@³ôª^ÞhÄö S*;Z_÷a½µàZ˶Kõúà\t¡Úw.î'6—õ”¾jÃ2—n*×uÿvëóQ9R¬‡ûéB°&‚ö†âhvapžð§ýÃà‹[šéézN2\®½5›C´÷m Ôß´—Cž;²}ÒYø\|÷‡@Ž.³®ö§å´€œ'ÀpŸó!ÂA@þ@¤ü=-‡ à<DÊùá   RþÆž–Cpž"å|ˆp€€¿)cOË!8O‘r>D8@À_ˆ”¿±§å€œ'€H9"„ à/DÊߨÓr@Î@¤œBð—"åoìi9 ç R·!øK‘ò7ö´€€ó)çC„ƒ€ü%€Hù{Z@Àyˆ”ó!ÂA@þ@¤ü=-‡ à<DÊùá   RþÆž–Cpž"å|ˆp€€¿)cOË!8O‘r>D8@À_ˆ”¿±§å€œ'€H9"„ à/DÊߨÓr@Î@¤œBð—"åoìi9 ç R·!øK‘ò7ö´€€ó)çC„ƒ€ü%€Hù{Z@Àyˆ”ó!ÂA@þ@¤ü=-‡ à<DÊùá   RþÆž–Cpž"å|ˆp€€¿)cOË!8O‘r>D8@À_ˆ”¿±§å€œ'€H9"„ à/DÊߨÓr@Î@¤œBð—"åoìi9 ç R·!øK‘ò7ö´€€ó)çC„ƒ€ü%€Hù{Z@Àyˆ”ó!ÂA@þ@¤ü=-‡ à<DÊùá   RþÆž–Cpž"å|ˆp€€¿)cOË!8O‘r>D8@À_ˆ”¿±§å€œ'€H9"„ à/DÊߨÓr@Î@¤œBð—"åoìi9 ç R·!øK‘ò7ö´€€ó)çC„ƒ€ü%€Hù{Z@Àyˆ”ó!ÂA@þ@¤ü=-‡ à<DÊùá   RþÆž–Cpž"å|ˆp€€¿)cOË!8O‘r>D8@À_ˆ”¿±§å€œ'€H9"„ à/DÊߨÓr@Î@¤œBð—"åoìi9 ç R·!øK‘ò7ö´€€ó)çC„ƒ€ü%€Hù{Z@Àyˆ”ó!ÂA@þ@¤ü=-‡ à<DÊùá   RþÆž–Cpž"å|ˆp€€¿)cOË!8O‘r>D8@À_ˆ”¿±§å€œ'€H9"„ à/DÊߨÓr@Î@¤œBð—"åoìi9 ç R·!øK‘ò7ö´€€ó)çC„ƒ€ü%€Hù{Z@Àyˆ”ó!ÂA@þÈó·é´p‘@Îõ3¤ò–MêÚÖ2üžy²ø?§ü’Ò]Òc✄:•ò‹7ÖÈCoÍzÎcµ‘{Ž/–â¶ÍŽ¡ a©†qã(@ ‰ÐD§—Ò»eÂäe²dÓ®´?1­d‡œ2¼­<{fï¤uïzo¶h&ó¯$;wWÊmS×ÊÙÏ,—WÏï›´>…{N€á¾=gÆð†ÀúmåÒãöÙ²¹lw\›·èö퉔ëÙ쯯–¢ÛfI·ÿ™-×üߪšrÛg=£·m•â_Ï’Ã^hEòÜÌRÉ¿q†4׿‘÷Í‹ííÐÿXýÀ¬§rÃk«cçmuÓL9ò‘E²xãÎ`w¬îƒ­—~wÌ‘ÜfÄÎiçNec],¿Ó5U•š}ÓJ¶Ë¡}Z×lG¿üî£ röÈöÒ²y3),È•kGw–w—l‹Vcû+@¤¾<…@¶èØ*/6„õ€ÞŒÃö o×F^nŽ<>}£·É“%:töÅÈàNùòдÄúó¯,ŸÖ3vš “—Êä ½dÇÃåº1ErÁs%áÓ×|ÿÍ»ë¤CöT®$k¯*Çn#7½¾¦f¿}yòóMòòy}¤ü¦á±sÚ¹SÙ-Gu‘½º¤ªR³ÏDê…Ù›cÜ]øúWWÉnÎÀæ\9HºjÛÍVlÞ%7ëÐß)‰Qù“IDATÃÛ»ùlˆT#@äÈf—ÜIL,ÊÊ+bÍÜ¥½§{Þ[/—Ð!¶}ßëåÌoÆz[çÉûw+ Û‡IëüfÒ«°j®Æz¥ÚËm–#§íU(sU„’Ù¤O7Ê9ÚSi¥ÇÚß¹úýõ[ãªÞ;®› îÜBrrrT8ÛÉ®*7ãê„7ŽØ&¼™òû´å;Ô¿v²ì§ƒeΕ¥cË\™øöÚ„cNzb‰ ¾kž<ªþ^ýíN û)h8æ¤ÎŽ#!à}ºÈ€Žùò˜Þ€/9°£üéóÚi!½ÛçÇÚ?{m™´¿uV‹‚¼œ¸í¾ÕuƒÂIã{È zc¿ãu2~X;¹AEÌ+jóÖí”ö*h™H¬ÚZlÆ>iÏ­©¬ägCjNÝBï–çï×A¸¾\3º¨¦Ü¾L9«w¬‡uÕ‹+åBí~zÙ€¸ýl4œ"Õpv o\~pG¹Vçš.Ô^ÒÄ·×ɯÇÖÎéìÖžËö†IÎËÔe6,¶qCÛÊçz#_¦Ùs·¾¹&Ö«úÍqÝÂUbß[DÄ®¢²2– ®˜ŸW÷ï†ë5Æ÷¶š$±bK¼Hç5‘½ùÈ.R¬Ã‚Xãøú¢Ûx>s&@àk&`½å•rïûë5‰¢BŽÓ¹¡ÀjOfu¤wìKõ¹wqÎ1µÕ”ínr—&³ÚƒÛ¨ÙxmÜQ!Í“ô¸‚ýýÙkâìØ\SpÞõÛwK¸çÖ[÷/ %r”ë|U0GÃçW#€H}5~ /XOèÒQåzÍ´»X碚…„âv'>Û$–ñ·VÅêWÚ3:jÒ¢”\,3ð©/6Ųoܥ“¼ú%znKÌØ¦Ï ÙßôûÎM7¼õâ{:×fóo–ÝhÏVÙóP6G˜Í—Ý]½ßÚ§ÎÝ]¸û`7Ÿ@ ŽK£ÎÌ) ¬"`‚aymÑ›ðÅ:Xª½«¾wÌ•~wΕ÷—nÓ,¾)Ûþðøîò«©k¤åÍ3õ™¥ªL¿dعK6k¼öXzêßÇË·Ë_uþ§)-œÿ‹#ºÄzrý¬mšæ¾K{J6ä˜Í¥Y"‰íz÷<ÉSñþyd¾*¨ËgÃäèƒsµù” ;GA€š„=©&ÁÊI!@ 1 RA‘s@€@“@¤š+'… Æ €H5EÎ@MBàÿToÛ^/²”IEND®B`‚edfbrowser_153_source/PaxHeaders.2978/nexfin2edf.h0000644000175000001440000000013212251654530020350 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/nexfin2edf.h0000644000175000001440000000455012251654530020105 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef UI_NEXFIN2EDFFORM_H #define UI_NEXFIN2EDFFORM_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "popup_messagewindow.h" #include "utils.h" #define MAX_SIGNALS 32 class UI_NEXFIN2EDFwindow : public QObject { Q_OBJECT public: UI_NEXFIN2EDFwindow(char *recent_dir=NULL, char *save_dir=NULL); private: QDialog *myobjectDialog; QPushButton *pushButton1, *pushButton2; QLabel *PatientnameLabel, *RecordingLabel, *DatetimeLabel; QLineEdit *PatientnameLineEdit, *RecordingLineEdit; QDateTimeEdit *StartDatetimeedit; QRadioButton *radio100button, *radio103button, *radio032button; QComboBox *analoginputscombobox; int file_type; char *recent_opendir, *recent_savedir; void enable_widgets(bool); private slots: void SelectFileButton(); void radiobuttonchecked(bool); }; #endif edfbrowser_153_source/PaxHeaders.2978/spectrum_dock.h0000644000175000001440000000013212251654530021162 xustar000000000000000030 mtime=1386699096.468032569 30 atime=1386699096.468032569 30 ctime=1386699096.468032569 edfbrowser_153_source/spectrum_dock.h0000644000175000001440000000607612251654530020724 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef SPECTRUMANALYZERDOCK_H #define SPECTRUMANALYZERDOCK_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "mainwindow.h" #include "signalcurve.h" #include "fourier.h" #include "popup_messagewindow.h" #include "utils.h" #include "filter.h" #include "ravg_filter.h" #include "third_party/fidlib/fidlib.h" #include "third_party/kiss_fft/kiss_fftr.h" class UI_Mainwindow; class UI_SpectrumDockWindow : public QObject { Q_OBJECT public: UI_SpectrumDockWindow(QWidget *parent); ~UI_SpectrumDockWindow(); UI_Mainwindow *mainwindow; QDialog *SpectrumDialog; QDockWidget *dock; struct signalcompblock *signalcomp; struct spectrum_markersblock *spectrum_color; void rescan(); void init(int); void clear(); private: QWidget *parentwindow; QHBoxLayout *hlayout1, *hlayout2, *hlayout3; QVBoxLayout *vlayout1, *vlayout2; SignalCurve *curve1; QTimer *t1; QSlider *amplitudeSlider, *spanSlider, *centerSlider; QLabel *spanLabel, *centerLabel, *amplitudeLabel; QRadioButton *sqrtButton, *colorBarButton; int samples, steps, sqrt_powerspectrum, dashboard; volatile int busy; double samplefreq, freqstep, maxvalue, maxvalue_sqrt, *buf1, *buf2, *buf3; char *viewbuf, signallabel[512], physdimension[9]; private slots: void update_curve(); void sliderMoved(int); void sqrtButtonClicked(bool); void colorBarButtonClicked(bool); void print_to_txt(); void setdashboard(); }; #endif edfbrowser_153_source/PaxHeaders.2978/pagetime_dialog.cpp0000644000175000001440000000013212251654530021765 xustar000000000000000030 mtime=1386699096.478032517 30 atime=1386699096.478032517 30 ctime=1386699096.478032517 edfbrowser_153_source/pagetime_dialog.cpp0000644000175000001440000000607012251654530021521 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "pagetime_dialog.h" UI_Userdefined_timepage_Dialog::UI_Userdefined_timepage_Dialog(QWidget *w_parent) { mainwindow = (UI_Mainwindow *)w_parent; set_diplaytime_dialog = new QDialog(w_parent); set_diplaytime_dialog->setMinimumSize(QSize(335, 200)); set_diplaytime_dialog->setMaximumSize(QSize(335, 200)); set_diplaytime_dialog->setWindowTitle("Set timescale"); set_diplaytime_dialog->setModal(TRUE); set_diplaytime_dialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); label1 = new QLabel(set_diplaytime_dialog); label1->setGeometry(QRect(70, 25, 110, 25)); label1->setText("hh:mm:ss:mmm"); timeEdit1 = new QTimeEdit(set_diplaytime_dialog); timeEdit1->setGeometry(QRect(65, 50, 110, 25)); timeEdit1->setDisplayFormat("hh:mm:ss.zzz"); timeEdit1->setMinimumTime(QTime(0, 0, 0, 0)); OKButton = new QPushButton(set_diplaytime_dialog); OKButton->setGeometry(QRect(10, 165, 100, 25)); OKButton->setText("OK"); CloseButton = new QPushButton(set_diplaytime_dialog); CloseButton->setGeometry(QRect(225, 165, 100, 25)); CloseButton->setText("Cancel"); QObject::connect(CloseButton, SIGNAL(clicked()), set_diplaytime_dialog, SLOT(close())); QObject::connect(OKButton, SIGNAL(clicked()), this, SLOT(okbutton_pressed())); set_diplaytime_dialog->exec(); } void UI_Userdefined_timepage_Dialog::okbutton_pressed() { long long milliseconds; if(!mainwindow->files_open) { set_diplaytime_dialog->close(); return; } milliseconds = (long long)(timeEdit1->time().hour()) * 3600000LL; milliseconds += (long long)(timeEdit1->time().minute()) * 60000LL; milliseconds += (long long)(timeEdit1->time().second()) * 1000LL; milliseconds += (long long)(timeEdit1->time().msec()); if(!milliseconds) { return; } mainwindow->pagetime = milliseconds * (TIME_DIMENSION / 1000); mainwindow->setup_viewbuf(); set_diplaytime_dialog->close(); } edfbrowser_153_source/PaxHeaders.2978/mainwindow.h0000644000175000001440000000013212251654530020474 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/mainwindow.h0000644000175000001440000003151112251654530020226 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef UI_VIEW_MAINFORM_H #define UI_VIEW_MAINFORM_H #include #include #include #include #include #include #include #include #include #include #include #include #ifdef Q_WS_X11 #include #include #endif #ifdef Q_WS_MAC #include #include #include #endif #ifdef Q_WS_WIN #include #include #ifndef CSIDL_COMMON_APPDATA #define CSIDL_COMMON_APPDATA 0x0023 // All Users\Application Data #endif #ifndef CSIDL_APPDATA #define CSIDL_APPDATA 0x001a // \Application Data #endif #ifndef CSIDL_PROGRAM_FILES #define CSIDL_PROGRAM_FILES 0x0026 // C:\Program Files #endif #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "viewcurve.h" #include "popup_messagewindow.h" #include "check_edf_file.h" #include "show_edf_hdr.h" #include "signals_dialog.h" #include "signal_chooser.h" #include "ascii_export.h" #include "edf_compat.h" #include "filter.h" #include "filter_dialog.h" #include "jump_dialog.h" #include "about_dialog.h" #include "edf_annotations.h" #include "annotations_dock.h" #include "options_dialog.h" #include "nk2edf.h" #include "xml.h" #include "save_montage_dialog.h" #include "load_montage_dialog.h" #include "view_montage_dialog.h" #include "show_actual_montage_dialog.h" #include "print_to_edf.h" #include "pagetime_dialog.h" #include "print_to_bdf.h" #include "ascii2edf.h" #include "fino2edf.h" #include "nexfin2edf.h" #include "edfplusd_cnv.h" #include "emsa2edf.h" #include "bdf2edf.h" #include "edit_annotation_dock.h" #include "popup_save_cancelwindow.h" #include "save_annots.h" #include "utils.h" #include "spectrumanalyzer.h" #include "bi9800.h" #include "export_annotations.h" #include "edit_predefined_mtg.h" #include "spectrum_dock.h" #include "signalcurve.h" #include "edf_annot_list.h" #include "reduce_signals.h" #include "header_editor.h" #include "biosemi2bdfplus.h" #include "bdf_triggers.h" #include "import_annotations.h" #include "ravg_filter.h" #include "wav2edf.h" #include "averager_curve_wnd.h" #include "ecg_filter.h" #include "ecg_export.h" #include "z_score_dialog.h" #include "z_ratio_filter.h" #include "raw2edf.h" #include "check_for_updates.h" #include "manscan2edf.h" #include "scp_ecg2edf.h" #include "unisens2edf.h" #include "third_party/fidlib/fidlib.h" class ViewCurve; class UI_Signalswindow; class UI_Annotationswindow; class UI_AnnotationEditwindow; class UI_SpectrumDockWindow; class UI_FreqSpectrumWindow; class UI_AverageCurveWindow; class UI_ZScoreWindow; class UI_Mainwindow : public QMainWindow { Q_OBJECT public: UI_Mainwindow(); ~UI_Mainwindow(); int files_open, signalcomps, totalviewbufsize, sel_viewtime, viewtime_sync, print_to_edf_active, annot_editor_active, show_annot_markers, show_baselines, annotations_edited, exit_in_progress, maxdftblocksize, dpix, dpiy, auto_dpi, clip_to_pane, auto_reload_mtg, read_biosemi_status_signal, read_nk_trigger_signal, live_stream_active, live_stream_update_interval, signal_averaging_active, powerlinefreq, mousewheelsens, average_ratio, average_upsidedown, average_bw, spectrum_bw, spectrum_sqrt, use_threads, check_for_updates, amplitude_doubler, timescale_doubler, viewtime_indicator_type, mainwindow_title_type; long long pagetime, maxfilesize_to_readin_annotations; char *viewbuf, viewtime_string[128], pagetime_string[64], recent_montagedir[MAX_PATH_LENGTH], recent_savedir[MAX_PATH_LENGTH], recent_opendir[MAX_PATH_LENGTH], predefined_mtg_path[MAXPREDEFINEDMONTAGES][MAX_PATH_LENGTH], recent_file_mtg_path[MAX_RECENTFILES][MAX_PATH_LENGTH], recent_colordir[MAX_PATH_LENGTH], cfg_app_version[17]; double pixelsizefactor, x_pixelsizefactor, average_period; struct{ double crossoverfreq; double z_threshold; double z_hysteresis; int zscore_page_len; int zscore_error_detection; } z_score_var; struct raw2edf_var_struct raw2edf_var; struct edfhdrblock *edfheaderlist[MAXFILES]; struct signalcompblock *signalcomp[MAXSIGNALS]; struct zoomhistoryblock *zoomhistory; struct annotationblock *annotationlist[MAXFILES]; struct annotationblock *annotationlist_backup; struct spectrum_markersblock *spectrum_colorbar; struct import_annotations_var_block *import_annotations_var; struct export_annotations_var_block *export_annotations_var; UI_Annotationswindow *annotations_dock[MAXFILES]; UI_AnnotationEditwindow *annotationEditDock; UI_FreqSpectrumWindow *spectrumdialog[MAXSPECTRUMDIALOGS]; UI_AverageCurveWindow *averagecurvedialog[MAXAVERAGECURVEDIALOGS]; UI_ZScoreWindow *zscoredialog[MAXZSCOREDIALOGS]; void setup_viewbuf(); void setMainwindowTitle(struct edfhdrblock *); int file_is_opened(const char *); void remove_recent_file_mtg_path(const char *); void get_rgbcolor_settings(struct xml_handle *, const char *, int, QColor *); struct signalcompblock * create_signalcomp_copy(struct signalcompblock *); ViewCurve *maincurve; QFont *myfont, *monofont; QAction *save_act, *load_predefined_mtg_act[MAXPREDEFINEDMONTAGES], *Escape_act; QActionGroup *timelock_act_group, *sel_viewtime_act_group; UI_SpectrumDockWindow *spectrumdock; private: QMenuBar *menubar; QMenu *filemenu, *signalmenu, *displaymenu, *amplitudemenu, *toolsmenu, *helpmenu, *printmenu, *filtermenu, // *math_func_menu, *timemenu, *windowmenu, *recent_filesmenu, *montagemenu, *patternmenu, *print_img_menu; char path[MAX_PATH_LENGTH], montagepath[MAX_PATH_LENGTH], recent_file_path[MAX_RECENTFILES][MAX_PATH_LENGTH]; #ifdef BK_MRS_project // temporary code for private use in a certain project // do not use this code, it will be removed in future QAction *keyboard_bk_mrs_project_act; FILE *bk_mrs_project_file; #endif QAction *former_page_Act, *shift_page_left_Act, *shift_page_right_Act, *next_page_Act, *shift_page_up_Act, *shift_page_down_Act, *page_div2, *page_mult2, *page_10m, *page_20m, *page_50m, *page_100m, *page_200m, *page_500m, *page_1, *page_2, *page_5, *page_10, *page_15, *page_20, *page_30, *page_60, *page_300, *page_1200, *page_3600, *page_user_defined, *page_whole_rec, *fit_to_pane, *fit_to_dc, *amp_00001, *amp_00002, *amp_00005, *amp_0001, *amp_0002, *amp_0005, *amp_001, *amp_002, *amp_005, *amp_01, *amp_02, *amp_05, *amp_1, *amp_2, *amp_5, *amp_10, *amp_20, *amp_50, *amp_100, *amp_200, *amp_500, *amp_1000, *amp_2000, *amp_5000, *amp_10000, *amp_20000, *amp_50000, *amp_plus, *amp_minus, *zoomback_Act, *zoomforward_Act, *recent_file[MAX_RECENTFILES], *offset_timesync_act, *absolut_timesync_act, *no_timesync_act, *user_def_sync_act, *sel_viewtime_act[MAXFILES]; QActionGroup *AmplitudeGroup, *DisplayGroup, *load_predefined_mtg_group; QTimer *live_stream_timer; QSplashScreen *splash; QPixmap *pixmap; QToolBar *slidertoolbar; QSlider *positionslider; int cmdlineargument, oldwindowheight; Check_for_updates *update_checker; void read_color_settings(); void read_recent_file_settings(); void read_general_settings(); void write_settings(); #ifdef Q_WS_WIN QString specialFolder(int); #endif long long check_edf_file_datarecords(struct edfhdrblock *); public slots: void remove_all_signals(); void edfplus_annotation_remove_duplicates(); private slots: void open_new_file(); void show_file_info(); void close_all_files(); void exit_program(); void signalproperties_dialog(); void filterproperties_dialog(); void add_signals_dialog(); void show_about_dialog(); void set_display_time(QAction *); void set_page_div2(); void set_page_mult2(); void set_display_time_whole_rec(); void set_amplitude(QAction *); void set_amplitude_div2(); void set_amplitude_mult2(); void fit_signals_to_pane(); void fit_signals_dc_offset(); void former_page(); void shift_page_left(); void shift_page_right(); void next_page(); void shift_page_up(); void shift_page_down(); void zoomback(); void forward(); void show_splashscreen(); void export_to_ascii(); void check_edf_compatibility(); void add_new_filter(); void remove_all_filters(); // void add_new_math_func(); // void remove_all_math_funcs(); void jump_to_dialog(); void jump_to_start(); void jump_to_end(); void show_annotations(); void show_options_dialog(); long long get_long_time(char *); void nk2edf_converter(); void set_timesync(QAction *); void set_timesync_reference(QAction *); void recent_file_action_func(QAction *); void sync_by_crosshairs(); void save_montage(); void load_montage(); void view_montage(); void show_this_montage(); void show_help(); void show_kb_shortcuts(); void print_to_edf(); void set_user_defined_display_time(); void print_to_bdf(); void print_to_img_640x480(); void print_to_img_800x600(); void print_to_img_1024x768(); void print_to_img_1280x1024(); void print_to_img_1600x1200(); void convert_ascii_to_edf(); void convert_fino_to_edf(); void convert_wave_to_edf(); void convert_nexfin_to_edf(); void edfd_converter(); void slider_moved(int); void convert_emsa_to_edf(); void bdf2edf_converter(); void set_dc_offset_to_zero(); void annotation_editor(); void save_file(); void unisens2edf_converter(); void BI98002edf_converter(); void export_annotations(); void load_predefined_mtg(QAction *); void edit_predefined_montages(); void show_spectrum_dock(); void page_3cmsec(); void reduce_signals(); void edit_header(); void biosemi2bdfplus_converter(); void import_annotations(); void open_stream(); void live_stream_timer_func(); void organize_signals(); void Escape_fun(); void export_ecg_rr_interval_to_ascii(); void convert_binary_to_edf(); void convert_manscan_to_edf(); void convert_scpecg_to_edf(); // void search_pattern(); #ifdef BK_MRS_project // temporary code for private use in a certain project // do not use this code, it will be removed in future void keyboard_bk_mrs_project_func(); #endif protected: void closeEvent(QCloseEvent *); }; #endif edfbrowser_153_source/PaxHeaders.2978/export_annotations.h0000644000175000001440000000013212251654530022256 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/export_annotations.h0000644000175000001440000000603412251654530022012 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef EXPORTANNOTATIONSFORM1_H #define EXPORTANNOTATIONSFORM1_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "mainwindow.h" #include "popup_messagewindow.h" #include "edflib.h" #include "utc_date_time.h" #include "edf_annot_list.h" class UI_Mainwindow; struct export_annotations_var_block { int separator; int format; int duration; }; class UI_ExportAnnotationswindow : public QObject { Q_OBJECT public: UI_ExportAnnotationswindow(QWidget *parent); UI_Mainwindow *mainwindow; private: QDialog *ExportAnnotsDialog; QListWidget *filelist; QPushButton *CloseButton, *ExportButton; QRadioButton *CSVRadioButton, *EDFplusRadioButton, *XMLRadioButton, *mergeRadioButton, *selectRadioButton, *asciiSecondsRadioButton, *asciiISOtimeRadioButton, *asciiISOtimedateRadioButton, *asciiISOtimeFractionRadioButton, *asciiISOtimedateFractionRadioButton; QGroupBox *formatGroupBox, *fileGroupBox, *asciiSettingsGroupBox; QVBoxLayout *formatVBoxLayout, *fileVBoxLayout, *asciiSettingsVBoxLayout; QHBoxLayout *asciiSettingsHBoxLayout; QComboBox *separatorBox; QLabel *separatorLabel; QCheckBox *durationCheckBox; private slots: void ExportButtonClicked(); void outputformatRadioButtonClicked(bool); }; #endif edfbrowser_153_source/PaxHeaders.2978/show_edf_hdr.h0000644000175000001440000000013212251654530020753 xustar000000000000000030 mtime=1386699096.468032569 30 atime=1386699096.468032569 30 ctime=1386699096.468032569 edfbrowser_153_source/show_edf_hdr.h0000644000175000001440000000513712251654530020512 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef SHOWEDFHDRFORM1_H #define SHOWEDFHDRFORM1_H #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "mainwindow.h" #include "utc_date_time.h" #include "special_button.h" #include "utils.h" class UI_Mainwindow; class UI_EDFhdrwindow : public QObject { Q_OBJECT public: UI_EDFhdrwindow(QWidget *parent); UI_Mainwindow *mainwindow; private: QDialog *EDFhdrDialog; QListWidget *filelist; QTableWidget *signallist; QLabel *label1, *label2, *label6, *label7, *label8, *label9, *label10, *label11, *label12, *label13, *label3, *label4, *label5, *label20, *label21; SpecialButton *label1a, *label2a, *label6a, *label7a, *label8a, *label9a, *label10a, *label11a, *label12a, *label13a, *label3a, *label4a, *label5a, *label20a, *label21a; QPushButton *pushButton1; int edfplus_layout; private slots: void show_params(int); }; #endif // SHOWEDFHDRORM1_H edfbrowser_153_source/PaxHeaders.2978/spectrum_dock.cpp0000644000175000001440000000013212251654530021515 xustar000000000000000030 mtime=1386699096.479032511 30 atime=1386699096.479032511 30 ctime=1386699096.479032511 edfbrowser_153_source/spectrum_dock.cpp0000644000175000001440000005067612251654530021264 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "spectrum_dock.h" UI_SpectrumDockWindow::UI_SpectrumDockWindow(QWidget *w_parent) { char str[600]; buf1 = NULL; buf2 = NULL; buf3 = NULL; busy = 0; dashboard = 0; signalcomp = NULL; mainwindow = (UI_Mainwindow *)w_parent; spectrum_color = mainwindow->spectrum_colorbar; sqrt_powerspectrum = 0; SpectrumDialog = new QDialog; dock = new QDockWidget("Power Spectral Density", w_parent); dock->setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetMovable); dock->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea); dock->setMinimumHeight(300); if(dashboard) { dock->setWidget(SpectrumDialog); } curve1 = new SignalCurve; curve1->setSignalColor(Qt::green); curve1->setBackgroundColor(Qt::black); curve1->setRasterColor(Qt::gray); curve1->setTraceWidth(0); curve1->setH_label("Hz"); curve1->setLowerLabel("Frequency"); if(sqrt_powerspectrum) { curve1->setV_label(physdimension); } else { snprintf(str, 512, "(%s)^2/Hz", physdimension); curve1->setV_label(str); } curve1->create_button("to Text"); if(!dashboard) { dock->setWidget(curve1); } amplitudeSlider = new QSlider; amplitudeSlider->setOrientation(Qt::Vertical); amplitudeSlider->setMinimum(1); amplitudeSlider->setMaximum(2000); amplitudeSlider->setValue(1000); amplitudeSlider->setInvertedAppearance(TRUE); amplitudeSlider->setMinimumSize(15, 110); amplitudeLabel = new QLabel; amplitudeLabel->setText("Amplitude"); amplitudeLabel->setMinimumSize(100, 15); amplitudeLabel->setAlignment(Qt::AlignHCenter); sqrtButton = new QRadioButton; sqrtButton->setMinimumSize(50, 20); sqrtButton->setText("Amplitude"); sqrtButton->setAutoExclusive(FALSE); colorBarButton = new QRadioButton; colorBarButton->setMinimumSize(50, 20); colorBarButton->setText("Colorbar"); colorBarButton->setAutoExclusive(FALSE); vlayout2 = new QVBoxLayout; vlayout2->setSpacing(20); vlayout2->addStretch(100); vlayout2->addWidget(amplitudeLabel, 0, Qt::AlignHCenter); vlayout2->addWidget(amplitudeSlider, 0, Qt::AlignHCenter); vlayout2->addWidget(sqrtButton); vlayout2->addWidget(colorBarButton); spanSlider = new QSlider; spanSlider->setOrientation(Qt::Horizontal); spanSlider->setMinimum(10); spanSlider->setMaximum(1000); spanSlider->setValue(1000); spanSlider->setMinimumSize(500, 15); spanLabel = new QLabel; spanLabel->setText("Span"); spanLabel->setMinimumSize(100, 15); spanLabel->setAlignment(Qt::AlignHCenter); centerSlider = new QSlider; centerSlider->setOrientation(Qt::Horizontal); centerSlider->setMinimum(0); centerSlider->setMaximum(1000); centerSlider->setValue(0); centerSlider->setMinimumSize(500, 15); centerLabel = new QLabel; centerLabel->setText("Center"); centerLabel->setMinimumSize(100, 15); centerLabel->setAlignment(Qt::AlignHCenter); hlayout1 = new QHBoxLayout; hlayout1->setSpacing(20); hlayout1->addLayout(vlayout2); if(dashboard) { hlayout1->addWidget(curve1, 100); } hlayout2 = new QHBoxLayout; hlayout2->setSpacing(20); hlayout2->addWidget(spanLabel); hlayout2->addWidget(spanSlider); hlayout2->addStretch(100); hlayout3 = new QHBoxLayout; hlayout3->setSpacing(20); hlayout3->addWidget(centerLabel); hlayout3->addWidget(centerSlider); hlayout3->addStretch(100); vlayout1 = new QVBoxLayout; vlayout1->setSpacing(20); vlayout1->addLayout(hlayout1); vlayout1->addLayout(hlayout2); vlayout1->addLayout(hlayout3); SpectrumDialog->setLayout(vlayout1); t1 = new QTimer(this); t1->setSingleShot(TRUE); QObject::connect(t1, SIGNAL(timeout()), this, SLOT(update_curve())); QObject::connect(amplitudeSlider, SIGNAL(valueChanged(int)), this, SLOT(sliderMoved(int))); QObject::connect(spanSlider, SIGNAL(valueChanged(int)), this, SLOT(sliderMoved(int))); QObject::connect(centerSlider, SIGNAL(valueChanged(int)), this, SLOT(sliderMoved(int))); QObject::connect(sqrtButton, SIGNAL(toggled(bool)), this, SLOT(sqrtButtonClicked(bool))); QObject::connect(colorBarButton, SIGNAL(toggled(bool)), this, SLOT(colorBarButtonClicked(bool))); QObject::connect(curve1, SIGNAL(extra_button_clicked()), this, SLOT(print_to_txt())); QObject::connect(curve1, SIGNAL(dashBoardClicked()), this, SLOT(setdashboard())); } void UI_SpectrumDockWindow::setdashboard() { if(dashboard) { dashboard = 0; dock->setWidget(curve1); } else { dashboard = 1; hlayout1->addWidget(curve1, 100); dock->setWidget(SpectrumDialog); } } void UI_SpectrumDockWindow::print_to_txt() { int i; char str[1024], path[MAX_PATH_LENGTH]; FILE *outputfile; path[0] = 0; if(mainwindow->recent_savedir[0]!=0) { strcpy(path, mainwindow->recent_savedir); strcat(path, "/"); } strcat(path, "spectrum.txt"); strcpy(path, QFileDialog::getSaveFileName(0, "Export to text (ASCII)", QString::fromLocal8Bit(path), "Text files (*.txt *.TXT)").toLocal8Bit().data()); if(!strcmp(path, "")) { return; } get_directory_from_path(mainwindow->recent_savedir, path, MAX_PATH_LENGTH); outputfile = fopen(path, "wb"); if(outputfile == NULL) { snprintf(str, 1024, "Can not open file %s for writing.", path); QMessageBox messagewindow(QMessageBox::Critical, "Error", QString::fromLocal8Bit(str)); messagewindow.exec(); return; } sprintf(str, "FFT Power Spectral Density (Power/%fHz)\n", freqstep); remove_trailing_zeros(str); fprintf(outputfile, "%s", str); fprintf(outputfile, "Signal: %s\n", signalcomp->signallabel); sprintf(str, "FFT blocksize: %i\n", mainwindow->maxdftblocksize); sprintf(str + strlen(str), "FFT resolution: %f Hz\n", freqstep); sprintf(str + strlen(str), "Data Samples: %i\n", samples); sprintf(str + strlen(str), "Power Samples: %i\n", steps); sprintf(str + strlen(str), "Samplefrequency: %f Hz\n", (double)signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].smp_per_record / ((double)signalcomp->edfhdr->long_data_record_duration / TIME_DIMENSION)); remove_trailing_zeros(str); fprintf(outputfile, "%s", str); for(i=0; ienableSpectrumColors(spectrum_color); } else { curve1->disableSpectrumColors(); } } void UI_SpectrumDockWindow::sqrtButtonClicked(bool value) { char str[600]; if(value == FALSE) { sqrt_powerspectrum = 0; sprintf(str, "Power Spectral Density %s", signallabel); dock->setWindowTitle(str); sprintf(str, "(%s)^2/Hz", physdimension); curve1->setV_label(str); } else { sqrt_powerspectrum = 1; sprintf(str, "Amplitude Spectrum %s", signallabel); curve1->setV_label(physdimension); dock->setWindowTitle(str); } sliderMoved(0); } void UI_SpectrumDockWindow::sliderMoved(int) { int startstep, stopstep, precision, spanstep; double max_freq, start_freq; spanstep = spanSlider->value() * steps / 1000; startstep = centerSlider->value() * (steps - spanstep) / 1000; stopstep = startstep + spanstep; if(sqrt_powerspectrum) { curve1->drawCurve(buf3 + startstep, stopstep - startstep, (maxvalue_sqrt * 1.05 * (double)amplitudeSlider->value()) / 1000.0, 0.0); } else { curve1->drawCurve(buf2 + startstep, stopstep - startstep, (maxvalue * 1.05 * (double)amplitudeSlider->value()) / 1000.0, 0.0); } max_freq = ((double)samplefreq / 2.0) * stopstep / steps; precision = 0; if(max_freq < 10.0) { precision = 1; } if(max_freq < 1.0) { precision = 2; } if(max_freq < 0.1) { precision = 3; } if(max_freq < 0.01) { precision = 4; } start_freq = ((double)samplefreq / 2.0) * startstep / steps; curve1->setH_RulerValues(start_freq, max_freq); centerLabel->setText(QString::number(start_freq + ((max_freq - start_freq) / 2.0), 'f', precision).append(" Hz").prepend("Center ")); spanLabel->setText(QString::number(max_freq - start_freq, 'f', precision).append(" Hz").prepend("Span ")); } void UI_SpectrumDockWindow::init(int signal_nr) { char str[600]; if(signal_nr < 0) { signalcomp = NULL; viewbuf = NULL; } else { signalcomp = mainwindow->signalcomp[signal_nr]; viewbuf = mainwindow->viewbuf; strcpy(signallabel, signalcomp->signallabel); strcpy(physdimension, signalcomp->physdimension); if(sqrt_powerspectrum) { curve1->setV_label(physdimension); } else { snprintf(str, 512, "(%s)^2/Hz", physdimension); curve1->setV_label(str); } dock->show(); t1->start(100); } } void UI_SpectrumDockWindow::rescan() { t1->start(100); } void UI_SpectrumDockWindow::clear() { int i; signalcomp = NULL; viewbuf = NULL; if(buf1 != NULL) { free(buf1); buf1 = NULL; } if(buf2 != NULL) { free(buf2); buf2 = NULL; } if(buf3 != NULL) { free(buf3); buf3 = NULL; } if(spectrum_color != NULL) { for(i=0; i < spectrum_color->items; i++) { spectrum_color->value[i] = 0.0; } } curve1->clear(); } void UI_SpectrumDockWindow::update_curve() { int i, j, k, n, dftblocksize, dftblocks, samplesleft, fft_outputbufsize; long long s, s2; char str[512]; double dig_value=0.0, f_tmp=0.0; union { unsigned int one; signed int one_signed; unsigned short two[2]; signed short two_signed[2]; unsigned char four[4]; } var; if(signalcomp == NULL) { return; } if(busy) { return; } viewbuf = mainwindow->viewbuf; if(viewbuf == NULL) { return; } busy = 1; curve1->setUpdatesEnabled(FALSE); samples = signalcomp->samples_on_screen; if(signalcomp->samples_on_screen > signalcomp->sample_stop) { samples = signalcomp->sample_stop; } samples -= signalcomp->sample_start; if((samples < 10) || (viewbuf == NULL)) { curve1->setUpdatesEnabled(TRUE); busy = 0; if(spectrum_color != NULL) { for(i=0; i < spectrum_color->items; i++) { spectrum_color->value[i] = 0.0; } } curve1->clear(); return; } if(buf1 != NULL) { free(buf1); } buf1 = (double *)malloc(sizeof(double) * signalcomp->samples_on_screen); if(buf1 == NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "The system was not able to provide enough resources (memory) to perform the requested action.\n" "Decrease the timescale and try again."); messagewindow.exec(); return; } samples = 0; for(s=signalcomp->sample_start; ssamples_on_screen; s++) { if(s>signalcomp->sample_stop) break; dig_value = 0.0; s2 = s + signalcomp->sample_timeoffset - signalcomp->sample_start; for(j=0; jnum_of_signals; j++) { if(signalcomp->edfhdr->bdf) { var.two[0] = *((unsigned short *)( viewbuf + signalcomp->viewbufoffset + (signalcomp->edfhdr->recordsize * (s2 / signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].smp_per_record)) + signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].buf_offset + ((s2 % signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].smp_per_record) * 3))); var.four[2] = *((unsigned char *)( viewbuf + signalcomp->viewbufoffset + (signalcomp->edfhdr->recordsize * (s2 / signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].smp_per_record)) + signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].buf_offset + ((s2 % signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].smp_per_record) * 3) + 2)); if(var.four[2]&0x80) { var.four[3] = 0xff; } else { var.four[3] = 0x00; } f_tmp = var.one_signed; } if(signalcomp->edfhdr->edf) { f_tmp = *(((short *)( viewbuf + signalcomp->viewbufoffset + (signalcomp->edfhdr->recordsize * (s2 / signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].smp_per_record)) + signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].buf_offset)) + (s2 % signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].smp_per_record)); } f_tmp += signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].offset; f_tmp *= signalcomp->factor[j]; dig_value += f_tmp; } for(k=0; kfilter_cnt; k++) { dig_value = first_order_filter(dig_value, signalcomp->filter[k]); } for(k=0; kravg_filter_cnt; k++) { if(s==signalcomp->sample_start) { ravg_filter_restore_buf(signalcomp->ravg_filter[k]); } dig_value = run_ravg_filter(dig_value, signalcomp->ravg_filter[k]); } for(k=0; kfidfilter_cnt; k++) { if(s==signalcomp->sample_start) { memcpy(signalcomp->fidbuf[k], signalcomp->fidbuf2[k], fid_run_bufsize(signalcomp->fid_run[k])); } dig_value = signalcomp->fidfuncp[k](signalcomp->fidbuf[k], dig_value); } if(signalcomp->ecg_filter != NULL) { if(s==signalcomp->sample_start) { ecg_filter_restore_buf(signalcomp->ecg_filter); } dig_value = run_ecg_filter(dig_value, signalcomp->ecg_filter); } if(s>=signalcomp->sample_start) { buf1[samples++] = dig_value * signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].bitvalue; } } samplefreq = (double)signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].smp_per_record / ((double)signalcomp->edfhdr->long_data_record_duration / TIME_DIMENSION); dftblocksize = mainwindow->maxdftblocksize; if(dftblocksize & 1) { dftblocksize--; } dftblocks = 1; if(dftblocksize < samples) { dftblocks = samples / dftblocksize; } else { dftblocksize = samples; } if(dftblocksize & 1) { dftblocksize--; } samplesleft = samples % dftblocksize; if(samplesleft & 1) { samplesleft--; } freqstep = samplefreq / (double)dftblocksize; fft_outputbufsize = dftblocksize / 2; steps = fft_outputbufsize; if(buf2 != NULL) { free(buf2); } buf2 = (double *)calloc(1, sizeof(double) * fft_outputbufsize); if(buf2 == NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "The system was not able to provide enough resources (memory) to perform the requested action."); messagewindow.exec(); free(buf1); buf1 = NULL; return; } if(buf3 != NULL) { free(buf3); } buf3 = (double *)malloc(sizeof(double) * fft_outputbufsize); if(buf3 == NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "The system was not able to provide enough resources (memory) to perform the requested action."); messagewindow.exec(); free(buf1); free(buf2); buf1 = NULL; buf2 = NULL; return; } maxvalue = 0.000001; maxvalue_sqrt = 0.000001; kiss_fftr_cfg cfg; kiss_fft_cpx *kiss_fftbuf; kiss_fftbuf = (kiss_fft_cpx *)malloc((fft_outputbufsize + 1) * sizeof(kiss_fft_cpx)); if(kiss_fftbuf == NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "The system was not able to provide enough resources (memory) to perform the requested action."); messagewindow.exec(); free(buf1); free(buf2); free(buf3); buf1 = NULL; buf2 = NULL; buf3 = NULL; return; } cfg = kiss_fftr_alloc(dftblocksize, 0, NULL, NULL); for(j=0; jecg_filter == NULL) { buf2[0] /= 2.0; // DC! } else { buf2[0] = 0.0; // Remove DC because heart rate is always a positive value } free(cfg); free(kiss_fftbuf); for(i=0; i maxvalue) { maxvalue = buf2[i]; } if(buf3[i] > maxvalue_sqrt) { maxvalue_sqrt = buf3[i]; } } } if(samplesleft) { dftblocks++; } if(buf1 != NULL) { free(buf1); buf1 = NULL; } sprintf(str, "FFT resolution: %f Hz %i blocks of %i samples", freqstep, dftblocks, dftblocksize); remove_trailing_zeros(str); curve1->setUpperLabel1(str); curve1->setUpperLabel2(signallabel); if(spectrum_color != NULL) { if(spectrum_color->items > 0) { spectrum_color->value[0] = 0.0; n = 0; for(j=0; jfreq[0]) { if(spectrum_color->method == 0) // sum { spectrum_color->value[0] += buf2[j]; } if(spectrum_color->method == 1) // peak { if(spectrum_color->value[0] < buf2[j]) { spectrum_color->value[0] = buf2[j]; } } if(spectrum_color->method == 2) // average { spectrum_color->value[0] += buf2[j]; n++; } } } if(spectrum_color->method == 2) // average { if(n) { spectrum_color->value[0] /= n; } } } for(i=1; i < spectrum_color->items; i++) { spectrum_color->value[i] = 0.0; n = 0; for(j=0; j spectrum_color->freq[i-1]) && (((freqstep * j) + (freqstep * 0.5)) < spectrum_color->freq[i])) { if(spectrum_color->method == 0) // sum { spectrum_color->value[i] += buf2[j]; } if(spectrum_color->method == 1) // peak { if(spectrum_color->value[i] < buf2[j]) { spectrum_color->value[i] = buf2[j]; } } if(spectrum_color->method == 2) // average { spectrum_color->value[i] += buf2[j]; n++; } } } if(spectrum_color->method == 2) // average { if(n) { spectrum_color->value[i] /= n; } } } } if(sqrt_powerspectrum) { snprintf(str, 512, "Amplitude Spectrum %s", signallabel); } else { snprintf(str, 512, "Power Spectral Density %s", signallabel); } dock->setWindowTitle(str); sliderMoved(0); curve1->setUpdatesEnabled(TRUE); busy = 0; } UI_SpectrumDockWindow::~UI_SpectrumDockWindow() { if(buf2 != NULL) { free(buf2); } if(buf3 != NULL) { free(buf3); } delete SpectrumDialog; } edfbrowser_153_source/PaxHeaders.2978/fourier.c0000644000175000001440000000013212251654530017766 xustar000000000000000030 mtime=1386699096.471032554 30 atime=1386699096.471032554 30 ctime=1386699096.471032554 edfbrowser_153_source/fourier.c0000644000175000001440000000610112251654530017515 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ /* ***************************************************************************** * * frequency analysis (power spectrum) * * Signal X sampled to N samples in X0, X1, X2, ... Xn-1 * Sample interval t(tau) seconds (i.e. 0.01 at 100 Hz samplefreq.) * * Powerspectrum P * Calculated for N/2 frequencypoints op P0, P1, P2, ... Pn/2-1 * Frequencyresolution dF(delta F) = 1/Nt (i.e. 0.1 with 10 seconds signal (N = 1000)) * * Calculate Pi, thus for frequency i * dF (i = 0, 1, 2, ... N/2-1) * * REi = {X0 * cos((2*pi*i/N) * 0) + X1 * cos((2*pi*i/N) * 1) + X2 * cos((2*pi*i/N) * 2) + ... + XN-1 * cos((2*pi*i/N) * (N-1))} * * IMi = {X0 * sin((2*pi*i/N) * 0) + X1 * sin((2*pi*i/N) * 1) + X2 * sin((2*pi*i/N) * 2) + ... + XN-1 * sin((2*pi*i/N) * (N-1))} * * Pi = ( (2/Fs) * {REi*REi + IMi*IMi} ) / N * ***************************************************************************** */ #include "fourier.h" #define _GNU_SOURCE #define DUB_PI 6.28318530717958623199592693708837032318115234375 float fourier_transform_get_power_float(int k, float *buf, int bufsize, float samplefreq) { int n; float var, rei=0.0, imi=0.0; var = (DUB_PI * k) / bufsize; for(n=0; n #include #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "ecg_filter.h" #include "signalcurve.h" class UI_StatisticWindow : public QObject { Q_OBJECT public: UI_StatisticWindow(struct signalcompblock *, long long); private: QDialog *StatDialog; QHBoxLayout *hlayout1, *hlayout1_1_1; QVBoxLayout *vlayout1_1, *vlayout2_1; QSlider *startSlider, *stopSlider; QLabel *Label1, *startLabel, *stopLabel; QPushButton *pushButton1; SignalCurve *curve1; int beat_cnt, bpm_distribution[300], max_val, start_ruler, end_ruler; private slots: void startSliderMoved(int); void stopSliderMoved(int); }; #endif // STATISTICS_DIALOGFORM1_H edfbrowser_153_source/PaxHeaders.2978/README.txt0000644000175000001440000000013212251654530017645 xustar000000000000000030 mtime=1386699096.503032385 30 atime=1386699096.503032385 30 ctime=1386699096.503032385 edfbrowser_153_source/README.txt0000644000175000001440000000112212251654530017372 0ustar00novarausers00000000000000 Requirements ============ Qt (minimum version 4.7.1 or later, preferable 4.8.5, Do not use Qt 5.x.x to compile EDFbrowser!!) http://qt-project.org/ The GCC compiler or MinGW on windows. Introduction ============ EDFbrowser is a Qt4 application and uses qmake as part of the build process. qmake is part of your Qt4 installation. Build and run without "installing" ================================== You need to have Qt and GCC (MinGW on Windows) installed. Extract the sourcefile and enter the following commands: qmake make Now you can run the program. edfbrowser_153_source/PaxHeaders.2978/colordialog.h0000644000175000001440000000013212251654530020616 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/colordialog.h0000644000175000001440000000552212251654530020353 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef COLORMENUFORM1_H #define COLORMENUFORM1_H #include #include #include #include #include #include "global.h" #include "special_button.h" class UI_Mainwindow; class UI_ColorMenuDialog : public QObject { Q_OBJECT public: UI_ColorMenuDialog(int *oldColor, QWidget *parent = NULL); private: int *color; QDialog *colormenu_dialog; QPushButton *CloseButton; SpecialButton *ColorButton1, *ColorButton2, *ColorButton3, *ColorButton4, *ColorButton5, *ColorButton6, *ColorButton7, *ColorButton8, *ColorButton9, *ColorButton10, *ColorButton11, *ColorButton12, *ColorButton13, *ColorButton14, *ColorButton15, *ColorButton16, *parentbutton; private slots: void ColorButton1_pressed(SpecialButton *); void ColorButton2_pressed(SpecialButton *); void ColorButton3_pressed(SpecialButton *); void ColorButton4_pressed(SpecialButton *); void ColorButton5_pressed(SpecialButton *); void ColorButton6_pressed(SpecialButton *); void ColorButton7_pressed(SpecialButton *); void ColorButton8_pressed(SpecialButton *); void ColorButton9_pressed(SpecialButton *); void ColorButton10_pressed(SpecialButton *); void ColorButton11_pressed(SpecialButton *); void ColorButton12_pressed(SpecialButton *); void ColorButton13_pressed(SpecialButton *); void ColorButton14_pressed(SpecialButton *); void ColorButton15_pressed(SpecialButton *); void ColorButton16_pressed(SpecialButton *); }; #endif // COLORMENUFORM1_H edfbrowser_153_source/PaxHeaders.2978/raw2edf.h0000644000175000001440000000013212251654530017652 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/raw2edf.h0000644000175000001440000000701412251654530017405 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef UI_RAW2EDFFORM_H #define UI_RAW2EDFFORM_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "popup_messagewindow.h" #include "xml.h" #include "utils.h" #include "edflib.h" #include "global.h" struct raw2edf_var_struct{ int sf; int chns; int phys_max; int straightbinary; int endianness; int samplesize; int offset; int skipblocksize; int skipbytes; char phys_dim[16]; }; class UI_RAW2EDFapp : public QObject { Q_OBJECT public: UI_RAW2EDFapp(struct raw2edf_var_struct *, char *recent_dir=NULL, char *save_dir=NULL); private: QDialog *raw2edfDialog; QLabel *SignalsLabel, *OffsetLabel, *SamplefreqLabel, *PatientnameLabel, *RecordingLabel, *DatetimeLabel, *SampleSizeLabel, *skipblocksizeLabel, *skipbytesLabel, *PhysicalMaximumLabel, *PhysicalDimensionLabel, *EncodingLabel, *variableTypeLabel, *EndiannessLabel; QLineEdit *PatientnameLineEdit, *RecordingLineEdit, *PhysicalDimensionLineEdit; QSpinBox *SignalsSpinbox, *OffsetSpinbox, *SamplefreqSpinbox, *SampleSizeSpinbox, *skipblocksizeSpinbox, *skipbytesSpinbox, *PhysicalMaximumSpinbox; QComboBox *EncodingCombobox, *EndiannessCombobox; QDateTimeEdit *StartDatetimeedit; QPushButton *GoButton, *CloseButton, *SaveButton, *LoadButton; char *recent_opendir, *recent_savedir; int edfsignals, offset, samplefrequency, edf_format; struct raw2edf_var_struct *raw2edf_var; private slots: void gobuttonpressed(); void savebuttonpressed(); void loadbuttonpressed(); void PhysicalDimensionLineEdited(QString); void sampleTypeChanged(int); }; #endif edfbrowser_153_source/PaxHeaders.2978/special_button.h0000644000175000001440000000013212251654530021333 xustar000000000000000030 mtime=1386699096.468032569 30 atime=1386699096.468032569 30 ctime=1386699096.468032569 edfbrowser_153_source/special_button.h0000644000175000001440000000364412251654530021073 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef SPECIALBUTTON_H #define SPECIALBUTTON_H #include #include #include #include class SpecialButton: public QWidget { Q_OBJECT public: SpecialButton(QWidget *parent=0); QSize sizeHint() const {return minimumSizeHint(); } QSize minimumSizeHint() const {return QSize(30,10); } public slots: void setColor(QColor); QColor color(); void setGlobalColor(int); int globalColor(); void setText(const char *); protected: void paintEvent(QPaintEvent *); QColor ButtonColor; void mouseReleaseEvent(QMouseEvent *); private: char buttonText[2048]; int global_Color; signals: void clicked(SpecialButton *); }; #endif edfbrowser_153_source/PaxHeaders.2978/view_montage_dialog.h0000644000175000001440000000013212251654530022323 xustar000000000000000030 mtime=1386699096.468032569 30 atime=1386699096.468032569 30 ctime=1386699096.468032569 edfbrowser_153_source/view_montage_dialog.h0000644000175000001440000000427312251654530022062 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef VIEWMONTAGEFORM1_H #define VIEWMONTAGEFORM1_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "mainwindow.h" #include "xml.h" #include "popup_messagewindow.h" #include "utils.h" class UI_Mainwindow; class UI_ViewMontagewindow : public QObject { Q_OBJECT public: UI_ViewMontagewindow(QWidget *parent); UI_Mainwindow *mainwindow; private: QDialog *ViewMontageDialog; QPushButton *CloseButton, *SelectButton; QBoxLayout *box; QHBoxLayout *hbox; QTreeView *tree; QStandardItemModel *t_model; char mtg_path[MAX_PATH_LENGTH], mtg_dir[MAX_PATH_LENGTH]; private slots: void SelectButtonClicked(); }; #endif // VIEWMONTAGEFORM1_H edfbrowser_153_source/PaxHeaders.2978/adjustfiltersettings.cpp0000644000175000001440000000013212251654530023134 xustar000000000000000030 mtime=1386699096.476032527 30 atime=1386699096.476032527 30 ctime=1386699096.476032527 edfbrowser_153_source/adjustfiltersettings.cpp0000644000175000001440000004126112251654530022671 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ /* type: 0 : highpass 1 : lowpass 2 : notch 3 : bandpass 4 : bandstop model: 0 : Butterworth 1 : Chebyshev 2 : Bessel 3 : moving average 0 : resonator */ #include "adjustfiltersettings.h" AdjustFilterSettings::AdjustFilterSettings(struct signalcompblock *signal_comp, QWidget *w_parent) { int i; char txtbuf[2048]; signalcomp = signal_comp; maincurve = (ViewCurve *)w_parent; mainwindow = maincurve->mainwindow; filtersettings_dialog = new QDialog(w_parent); filtersettings_dialog->setMinimumSize(360, 255); filtersettings_dialog->setMaximumSize(360, 255); strcpy(txtbuf, "Filter settings "); if(signalcomp->alias[0] != 0) { strcat(txtbuf, signalcomp->alias); } else { strcat(txtbuf, signalcomp->signallabel); } filtersettings_dialog->setWindowTitle(txtbuf); filtersettings_dialog->setModal(TRUE); filtersettings_dialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); for(i=0; i<5; i++) { label[i] = new QLabel(filtersettings_dialog); label[i]->setGeometry(10, 10 + (i * 35), 100, 25); } label[0]->setText("Filter"); label[1]->setText("Order"); label[2]->setText("Frequency"); label[3]->setText("Frequency 2"); label[3]->setVisible(FALSE); label[4]->setText("Stepsize"); filterbox = new QComboBox(filtersettings_dialog); filterbox->setGeometry(120, 10, 230, 25); orderbox = new QSpinBox(filtersettings_dialog); orderbox->setGeometry(120, 45, 100, 25); orderbox->setSuffix("th order"); orderbox->setMinimum(1); orderbox->setMaximum(8); orderbox->setValue(1); orderbox->setSingleStep(1); freq1box = new QDoubleSpinBox(filtersettings_dialog); freq1box->setGeometry(120, 80, 180, 25); freq1box->setDecimals(6); freq1box->setSuffix(" Hz"); freq1box->setMinimum(0.0001); freq1box->setMaximum(100000.0); freq1box->setValue(1.0); freq1box->setSingleStep(1.0); freq2box = new QDoubleSpinBox(filtersettings_dialog); freq2box->setGeometry(120, 115, 180, 25); freq2box->setDecimals(6); freq2box->setSuffix(" Hz"); freq2box->setMinimum(0.0001); freq2box->setMaximum(100000.0); freq2box->setValue(2.0); freq2box->setVisible(FALSE); freq2box->setSingleStep(1.0); stepsizebox = new QComboBox(filtersettings_dialog); stepsizebox->setGeometry(120, 150, 80, 25); stepsizebox->addItem("0.01Hz"); stepsizebox->addItem("0.1Hz"); stepsizebox->addItem("1Hz"); stepsizebox->addItem("10Hz"); stepsizebox->addItem("100Hz"); stepsizebox->setCurrentIndex(2); CloseButton = new QPushButton(filtersettings_dialog); CloseButton->setGeometry(270, 220, 80, 25); CloseButton->setText("Close"); filter_cnt = 0; for(i=0; ifidfilter_cnt; i++) { txtbuf[0] = 0; type = signalcomp->fidfilter_type[i]; model = signalcomp->fidfilter_model[i]; order = signalcomp->fidfilter_order[i]; ripple = signalcomp->fidfilter_ripple[i]; if(type == 0) { if(model == 0) { sprintf(txtbuf, "HighPass Butterworth"); } if(model == 1) { sprintf(txtbuf, "HighPass Chebyshev %.1fdB ripple", ripple); } if(model == 2) { sprintf(txtbuf, "HighPass Bessel"); } } if(type == 1) { if(model == 0) { sprintf(txtbuf, "LowPass Butterworth"); } if(model == 1) { sprintf(txtbuf, "LowPass Chebyshev %.1fdB ripple", ripple); } if(model == 2) { sprintf(txtbuf, "LowPass Bessel"); } } if(type == 2) { sprintf(txtbuf + strlen(txtbuf), "Notch (resonator)"); } if(type == 3) { if(model == 0) { sprintf(txtbuf, "BandPass Butterworth"); } if(model == 1) { sprintf(txtbuf, "BandPass Chebyshev %.1fdB ripple", ripple); } if(model == 2) { sprintf(txtbuf, "BandPass Bessel"); } } if(type == 4) { if(model == 0) { sprintf(txtbuf, "BandStop Butterworth"); } if(model == 1) { sprintf(txtbuf, "BandStop Chebyshev %.1fdB ripple", ripple); } if(model == 2) { sprintf(txtbuf, "BandStop Bessel"); } } filterbox->addItem(txtbuf); brand[filter_cnt++] = 0; } for(i=0; iravg_filter_cnt; i++) { type = signalcomp->ravg_filter_type[i]; size = signalcomp->ravg_filter_size[i]; if(type == 0) { filterbox->addItem("Highpass Moving Average"); } if(type == 1) { filterbox->addItem("Lowpass Moving Average"); } brand[filter_cnt++] = 1; } filterboxchanged(filterbox->currentIndex()); QObject::connect(freq1box, SIGNAL(valueChanged(double)), this, SLOT(freqbox1valuechanged(double))); QObject::connect(freq2box, SIGNAL(valueChanged(double)), this, SLOT(freqbox2valuechanged(double))); QObject::connect(orderbox, SIGNAL(valueChanged(int)), this, SLOT(orderboxvaluechanged(int))); QObject::connect(filterbox, SIGNAL(currentIndexChanged(int)), this, SLOT(filterboxchanged(int))); QObject::connect(stepsizebox, SIGNAL(currentIndexChanged(int)), this, SLOT(stepsizeboxchanged(int))); QObject::connect(CloseButton, SIGNAL(clicked()), filtersettings_dialog, SLOT(close())); filtersettings_dialog->exec(); } void AdjustFilterSettings::orderboxvaluechanged(int) { int j; for(j=0; j<10; j++) qApp->processEvents(); update_filter(); } void AdjustFilterSettings::freqbox1valuechanged(double value) { int j; if((type == 3) || (type == 4)) { if(freq2box->value() < (value * 1.12)) { QObject::disconnect(freq2box, SIGNAL(valueChanged(double)), this, SLOT(freqbox2valuechanged(double))); freq2box->setValue(value * 1.12); QObject::connect(freq2box, SIGNAL(valueChanged(double)), this, SLOT(freqbox2valuechanged(double))); } } for(j=0; j<10; j++) qApp->processEvents(); update_filter(); } void AdjustFilterSettings::freqbox2valuechanged(double value) { int j; if(freq1box->value() > (value * 0.9)) { QObject::disconnect(freq1box, SIGNAL(valueChanged(double)), this, SLOT(freqbox1valuechanged(double))); freq1box->setValue(value * 0.9); QObject::connect(freq1box, SIGNAL(valueChanged(double)), this, SLOT(freqbox1valuechanged(double))); } for(j=0; j<10; j++) qApp->processEvents(); update_filter(); } void AdjustFilterSettings::filterboxchanged(int i) { int n; if(i < 0) { return; } QObject::disconnect(freq1box, SIGNAL(valueChanged(double)), this, SLOT(freqbox1valuechanged(double))); QObject::disconnect(freq2box, SIGNAL(valueChanged(double)), this, SLOT(freqbox2valuechanged(double))); QObject::disconnect(orderbox, SIGNAL(valueChanged(int)), this, SLOT(orderboxvaluechanged(int))); if(brand[i] == 0) // fidfilter { n = i; frequency1 = signalcomp->fidfilter_freq[n]; frequency2 = signalcomp->fidfilter_freq2[n]; type = signalcomp->fidfilter_type[n]; model = signalcomp->fidfilter_model[n]; order = signalcomp->fidfilter_order[n]; ripple = signalcomp->fidfilter_ripple[n]; freq1box->setValue(frequency1); label[1]->setText("Order"); label[2]->setText("Frequency"); freq1box->setVisible(TRUE); stepsizebox->clear(); stepsizebox->addItem("0.01Hz"); stepsizebox->addItem("0.1Hz"); stepsizebox->addItem("1Hz"); stepsizebox->addItem("10Hz"); stepsizebox->addItem("100Hz"); stepsizebox->setCurrentIndex(2); if((type == 3) || (type == 4)) { freq2box->setValue(frequency2); label[3]->setVisible(TRUE); freq2box->setVisible(TRUE); orderbox->setMinimum(2); orderbox->setSingleStep(2); orderbox->setMaximum(16); } else { freq2box->setValue(0.0); label[3]->setVisible(FALSE); freq2box->setVisible(FALSE); orderbox->setMinimum(1); orderbox->setSingleStep(1); orderbox->setMaximum(8); } if(type == 2) { orderbox->setPrefix("Q-factor "); orderbox->setSuffix(""); orderbox->setMaximum(100); orderbox->setMinimum(3); } else { orderbox->setPrefix(""); orderbox->setSuffix("th order"); } orderbox->setValue(order); } if(brand[i] == 1) // moving average filter { n = i - signalcomp->fidfilter_cnt; type = signalcomp->ravg_filter_type[n]; size = signalcomp->ravg_filter_size[n]; stepsizebox->clear(); stepsizebox->addItem("1"); stepsizebox->addItem("10"); stepsizebox->addItem("100"); stepsizebox->addItem("1000"); stepsizebox->setCurrentIndex(0); label[1]->setText("Size"); label[2]->setText(""); freq1box->setVisible(FALSE); label[3]->setVisible(FALSE); freq2box->setVisible(FALSE); orderbox->setMinimum(2); orderbox->setSingleStep(1); orderbox->setMaximum(10000); orderbox->setPrefix(""); orderbox->setSuffix(" samples"); orderbox->setValue(size); } QObject::connect(freq1box, SIGNAL(valueChanged(double)), this, SLOT(freqbox1valuechanged(double))); QObject::connect(freq2box, SIGNAL(valueChanged(double)), this, SLOT(freqbox2valuechanged(double))); QObject::connect(orderbox, SIGNAL(valueChanged(int)), this, SLOT(orderboxvaluechanged(int))); } void AdjustFilterSettings::update_filter() { char *filter_spec, spec_str_1[256], spec_str_2[256], *err=NULL; filter_nr = filterbox->currentIndex(); if(filter_nr < 0) { return; } if(brand[filter_nr] == 0) // fidfilter { frequency1 = freq1box->value(); frequency2 = freq2box->value(); order = orderbox->value(); if(type < 3) { if(frequency1 >= ((signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].smp_per_record / signalcomp->edfhdr->data_record_duration) / 2.0)) { frequency1 = (signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].smp_per_record / signalcomp->edfhdr->data_record_duration) / 2.0; frequency1 -= freq1box->singleStep(); freq1box->setValue(frequency1); } } else { if(frequency2 >= ((signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].smp_per_record / signalcomp->edfhdr->data_record_duration) / 2.0)) { frequency2 = (signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].smp_per_record / signalcomp->edfhdr->data_record_duration) / 2.0; frequency2 -= freq2box->singleStep(); freq2box->setValue(frequency2); } if(frequency1 >= frequency2 * 0.9) { frequency1 = frequency2 * 0.9; freq1box->setValue(frequency1); } } if(type < 3) { if(frequency1 >= ((signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].smp_per_record / signalcomp->edfhdr->data_record_duration) / 2.0)) { UI_Messagewindow errormessage("Error", "The frequency must be less than: samplerate / 2"); return; } } else { if(frequency2 >= ((signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].smp_per_record / signalcomp->edfhdr->data_record_duration) / 2.0)) { UI_Messagewindow errormessage("Error", "The frequency must be less than: samplerate / 2"); return; } } spec_str_1[0] = 0; if(type == 0) { if(model == 0) { sprintf(spec_str_1, "HpBu%i/%f", order, frequency1); } if(model == 1) { sprintf(spec_str_1, "HpCh%i/%f/%f", order, ripple, frequency1); } if(model == 2) { sprintf(spec_str_1, "HpBe%i/%f", order, frequency1); } } if(type == 1) { if(model == 0) { sprintf(spec_str_1, "LpBu%i/%f", order, frequency1); } if(model == 1) { sprintf(spec_str_1, "LpCh%i/%f/%f", order, ripple, frequency1); } if(model == 2) { sprintf(spec_str_1, "LpBe%i/%f", order, frequency1); } } if(type == 2) { sprintf(spec_str_1, "BsRe/%i/%f", order, frequency1); } if(type == 3) { if(model == 0) { sprintf(spec_str_1, "BpBu%i/%f-%f", order, frequency1, frequency2); } if(model == 1) { sprintf(spec_str_1, "BpCh%i/%f/%f-%f", order, ripple, frequency1, frequency2); } if(model == 2) { sprintf(spec_str_1, "BpBe%i/%f-%f", order, frequency1, frequency2); } } if(type == 4) { if(model == 0) { sprintf(spec_str_1, "BsBu%i/%f-%f", order, frequency1, frequency2); } if(model == 1) { sprintf(spec_str_1, "BsCh%i/%f/%f-%f", order, ripple, frequency1, frequency2); } if(model == 2) { sprintf(spec_str_1, "BsBe%i/%f-%f", order, frequency1, frequency2); } } strcpy(spec_str_2, spec_str_1); filter_spec = spec_str_2; free(signalcomp->fidfilter[filter_nr]); fid_run_free(signalcomp->fid_run[filter_nr]); fid_run_freebuf(signalcomp->fidbuf[filter_nr]); fid_run_freebuf(signalcomp->fidbuf2[filter_nr]); err = fid_parse(((double)(signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].smp_per_record)) / signalcomp->edfhdr->data_record_duration, &filter_spec, &signalcomp->fidfilter[filter_nr]); if(err != NULL) { UI_Messagewindow errormessage("Error", err); free(err); return; } signalcomp->fid_run[filter_nr] = fid_run_new(signalcomp->fidfilter[filter_nr], &signalcomp->fidfuncp[filter_nr]); signalcomp->fidbuf[filter_nr] = fid_run_newbuf(signalcomp->fid_run[filter_nr]); signalcomp->fidbuf2[filter_nr] = fid_run_newbuf(signalcomp->fid_run[filter_nr]); signalcomp->fidfilter_freq[filter_nr] = frequency1; signalcomp->fidfilter_freq2[filter_nr] = frequency2; signalcomp->fidfilter_order[filter_nr] = order; } if(brand[filter_nr] == 1) // moving average filter { filter_nr -= signalcomp->fidfilter_cnt; size = orderbox->value(); free_ravg_filter(signalcomp->ravg_filter[filter_nr]); signalcomp->ravg_filter[filter_nr] = create_ravg_filter(type, size); if(signalcomp->ravg_filter[filter_nr] == NULL) { UI_Messagewindow errormessage("Error", "An error occurred while creating a moving average filter."); return; } signalcomp->ravg_filter_size[filter_nr] = size; } mainwindow->setup_viewbuf(); } void AdjustFilterSettings::stepsizeboxchanged(int index) { int n; n = filterbox->currentIndex(); if(n < 0) { return; } if(brand[n] == 0) // fidfilter { switch(index) { case 0: freq1box->setSingleStep(0.01); freq2box->setSingleStep(0.01); break; case 1: freq1box->setSingleStep(0.1); freq2box->setSingleStep(0.1); break; case 2: freq1box->setSingleStep(1.0); freq2box->setSingleStep(1.0); break; case 3: freq1box->setSingleStep(10.0); freq2box->setSingleStep(10.0); break; case 4: freq1box->setSingleStep(100.0); freq2box->setSingleStep(100.0); break; } } if(brand[n] == 1) // moving average filter { switch(index) { case 0: orderbox->setSingleStep(1); break; case 1: orderbox->setSingleStep(10); break; case 2: orderbox->setSingleStep(100); break; case 3: orderbox->setSingleStep(1000); break; } } } edfbrowser_153_source/PaxHeaders.2978/header_editor.cpp0000644000175000001440000000013212251654530021451 xustar000000000000000030 mtime=1386699096.478032517 30 atime=1386699096.478032517 30 ctime=1386699096.478032517 edfbrowser_153_source/header_editor.cpp0000644000175000001440000012464512251654530021216 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "header_editor.h" #if defined(__APPLE__) || defined(__MACH__) || defined(__APPLE_CC__) #define fopeno fopen #else #define fseeko fseeko64 #define ftello ftello64 #define fopeno fopen64 #endif UI_headerEditorWindow::UI_headerEditorWindow(QWidget *w_parent) { mainwindow = (UI_Mainwindow *)w_parent; setWindowTitle("EDF+/BDF+ header editor"); edf = 0; bdf = 0; edfplus = 0; bdfplus = 0; edfsignals = 0; file = NULL; setMinimumSize(690, 525); setMaximumSize(690, 525); tabholder = new QTabWidget(this); tabholder->setGeometry(0, 0, 690, 455); tab1 = new QWidget; tab2 = new QWidget; fileNameLabel = new QLabel(tab1); fileNameLabel->setGeometry(10, 10, 670, 25); startTimeDateLabel = new QLabel(tab1); startTimeDateLabel->setGeometry(10, 45, 80, 25); startTimeDateLabel->setText("Starttime"); startTimeDateLabel->setVisible(FALSE); startTimeDate = new QDateTimeEdit(tab1); startTimeDate->setGeometry(100, 45, 250, 25); startTimeDate->setDisplayFormat("dd.MM.yyyy hh:mm:ss"); startTimeDate->setMinimumDate(QDate(1970, 1, 1)); startTimeDate->setMaximumDate(QDate(2299, 12, 31)); startTimeDate->setVisible(FALSE); label1 = new QLabel(tab1); label1->setGeometry(10, 80, 80, 25); label1->setText("Subject"); label1->setVisible(FALSE); lineEdit1 = new QLineEdit(tab1); lineEdit1->setGeometry(100, 80, 580, 25); lineEdit1->setMaxLength(80); lineEdit1->setVisible(FALSE); label2 = new QLabel(tab1); label2->setGeometry(10, 115, 80, 25); label2->setText("Recording"); label2->setVisible(FALSE); lineEdit2 = new QLineEdit(tab1); lineEdit2->setGeometry(100, 115, 580, 25); lineEdit2->setMaxLength(80); lineEdit2->setVisible(FALSE); label3 = new QLabel(tab1); label3->setGeometry(10, 80, 80, 25); label3->setText("Subject code"); label3->setVisible(FALSE); lineEdit3 = new QLineEdit(tab1); lineEdit3->setGeometry(100, 80, 580, 25); lineEdit3->setMaxLength(80); lineEdit3->setVisible(FALSE); label4 = new QLabel(tab1); label4->setGeometry(10, 115, 80, 25); label4->setText("Subject name"); label4->setVisible(FALSE); lineEdit4 = new QLineEdit(tab1); lineEdit4->setGeometry(100, 115, 580, 25); lineEdit4->setMaxLength(80); lineEdit4->setVisible(FALSE); label11 = new QLabel(tab1); label11->setGeometry(10, 150, 80, 25); label11->setText("Gender"); label11->setVisible(FALSE); comboBox1 = new QComboBox(tab1); comboBox1->setGeometry(100, 150, 125, 25); comboBox1->addItem("unknown"); comboBox1->addItem("male"); comboBox1->addItem("female"); comboBox1->setVisible(FALSE); charsleft1Label = new QLabel(tab1); charsleft1Label->setGeometry(500, 150, 120, 25); charsleft1Label->setVisible(FALSE); label12 = new QLabel(tab1); label12->setGeometry(10, 185, 80, 25); label12->setText("Birthdate"); label12->setVisible(FALSE); dateEdit1 = new QDateEdit(tab1); dateEdit1->setGeometry(100, 185, 125, 25); dateEdit1->setDisplayFormat("d MMM yyyy"); dateEdit1->setVisible(FALSE); checkBox1 = new QCheckBox("No birthdate", tab1); checkBox1->setGeometry(245, 185, 125, 25); checkBox1->setTristate(FALSE); checkBox1->setCheckState(Qt::Unchecked); checkBox1->setVisible(FALSE); label5 = new QLabel(tab1); label5->setGeometry(10, 220, 80, 25); label5->setText("Additional info"); label5->setVisible(FALSE); lineEdit5 = new QLineEdit(tab1); lineEdit5->setGeometry(100, 220, 580, 25); lineEdit5->setMaxLength(80); lineEdit5->setVisible(FALSE); label6 = new QLabel(tab1); label6->setGeometry(10, 255, 80, 25); label6->setText("Admin. code"); label6->setVisible(FALSE); lineEdit6 = new QLineEdit(tab1); lineEdit6->setGeometry(100, 255, 580, 25); lineEdit6->setMaxLength(80); lineEdit6->setVisible(FALSE); label7 = new QLabel(tab1); label7->setGeometry(10, 290, 80, 25); label7->setText("Technician"); label7->setVisible(FALSE); lineEdit7 = new QLineEdit(tab1); lineEdit7->setGeometry(100, 290, 580, 25); lineEdit7->setMaxLength(80); lineEdit7->setVisible(FALSE); label8 = new QLabel(tab1); label8->setGeometry(10, 325, 80, 25); label8->setText("Device"); label8->setVisible(FALSE); lineEdit8 = new QLineEdit(tab1); lineEdit8->setGeometry(100, 325, 580, 25); lineEdit8->setMaxLength(80); lineEdit8->setVisible(FALSE); label9 = new QLabel(tab1); label9->setGeometry(10, 360, 80, 25); label9->setText("Additional info"); label9->setVisible(FALSE); lineEdit9 = new QLineEdit(tab1); lineEdit9->setGeometry(100, 360, 580, 25); lineEdit9->setMaxLength(80); lineEdit9->setVisible(FALSE); charsleft2Label = new QLabel(tab1); charsleft2Label->setGeometry(500, 395, 120, 25); charsleft2Label->setVisible(FALSE); signallist = new QTableWidget(tab2); signallist->setGeometry(10, 10, 670, 375); signallist->setSelectionMode(QAbstractItemView::NoSelection); signallist->setEditTriggers(QAbstractItemView::NoEditTriggers); signallist->setColumnCount(4); signallist->setSelectionMode(QAbstractItemView::NoSelection); signallist->setColumnWidth(0, 180); signallist->setColumnWidth(1, 120); signallist->setColumnWidth(2, 520); signallist->setColumnWidth(3, 520); QStringList horizontallabels; horizontallabels += "Label"; horizontallabels += "Physical dimension"; horizontallabels += "Prefilter"; horizontallabels += "Transducer"; signallist->setHorizontalHeaderLabels(horizontallabels); pushButton1 = new QPushButton(this); pushButton1->setGeometry(580, 475, 100, 25); pushButton1->setText("Close"); pushButton2 = new QPushButton(this); pushButton2->setGeometry(200, 475, 100, 25); pushButton2->setText("Save"); pushButton3 = new QPushButton(this); pushButton3->setGeometry(10, 475, 100, 25); pushButton3->setText("Select file"); connect(pushButton1, SIGNAL(clicked()), this, SLOT(close())); connect(pushButton2, SIGNAL(clicked()), this, SLOT(save_hdr())); connect(pushButton3, SIGNAL(clicked()), this, SLOT(open_file())); tabholder->addTab(tab1, "Header"); tabholder->addTab(tab2, "Signals"); hdr = (char *)malloc(256 * 2050); QMessageBox messagewindow(QMessageBox::Warning, "Warning", "Always make a backup copy of your file before using this tool!"); messagewindow.exec(); exec(); } void UI_headerEditorWindow::closeEvent(QCloseEvent *cl_event) { if(file != NULL) { fclose(file); } if(hdr != NULL) { free(hdr); } cl_event->accept(); } void UI_headerEditorWindow::open_file() { long long filesize; if(file != NULL) { fclose(file); file = NULL; } edf = 0; bdf = 0; edfplus = 0; bdfplus = 0; edfsignals = 0; disconnect(lineEdit3, SIGNAL(textEdited(const QString &)), this, SLOT(calculate_chars_left_name(const QString &))); disconnect(lineEdit4, SIGNAL(textEdited(const QString &)), this, SLOT(calculate_chars_left_name(const QString &))); disconnect(lineEdit5, SIGNAL(textEdited(const QString &)), this, SLOT(calculate_chars_left_name(const QString &))); disconnect(lineEdit6, SIGNAL(textEdited(const QString &)), this, SLOT(calculate_chars_left_recording(const QString &))); disconnect(lineEdit7, SIGNAL(textEdited(const QString &)), this, SLOT(calculate_chars_left_recording(const QString &))); disconnect(lineEdit8, SIGNAL(textEdited(const QString &)), this, SLOT(calculate_chars_left_recording(const QString &))); disconnect(lineEdit9, SIGNAL(textEdited(const QString &)), this, SLOT(calculate_chars_left_recording(const QString &))); lineEdit3->setMaxLength(80); lineEdit4->setMaxLength(80); lineEdit5->setMaxLength(80); lineEdit6->setMaxLength(80); lineEdit7->setMaxLength(80); lineEdit8->setMaxLength(80); lineEdit9->setMaxLength(80); lineEdit1->clear(); lineEdit2->clear(); lineEdit3->clear(); lineEdit4->clear(); lineEdit5->clear(); lineEdit6->clear(); lineEdit7->clear(); lineEdit8->clear(); lineEdit9->clear(); signallist->setRowCount(0); fileNameLabel->clear(); if(hdr==NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "A memory allocation error occurred. (hdr)"); messagewindow.exec(); return; } strcpy(path, QFileDialog::getOpenFileName(0, "Open file", QString::fromLocal8Bit(mainwindow->recent_opendir), "EDF/BDF files (*.edf *.EDF *.bdf *.BDF)").toLocal8Bit().data()); if(!strcmp(path, "")) { return; } get_directory_from_path(mainwindow->recent_opendir, path, MAX_PATH_LENGTH); if(mainwindow->file_is_opened(path)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Selected file is in use."); messagewindow.exec(); return; } file = fopeno(path, "r+b"); if(file==NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not open file."); messagewindow.exec(); return; } rewind(file); if(fread(hdr, 256, 1, file) != 1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not read from file."); messagewindow.exec(); fclose(file); file = NULL; return; } if(!(strncmp(hdr, "0 ", 8))) edf = 1; if((!(strncmp(hdr + 1, "BIOSEMI", 7))) && (((unsigned char *)hdr)[0] == 255)) { bdf = 1; } if((!edf) && (!bdf)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "File is not a valid EDF or BDF file.\n" "Invalid version."); messagewindow.exec(); fclose(file); file = NULL; return; } edfsignals = antoi(hdr + 252, 4); if(edfsignals < 1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Invalid number of signals in header (less than 1)"); messagewindow.exec(); fclose(file); file = NULL; return; } if(edfsignals > 2049) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Number of signals in header is more than 2048.\n" "This tool can not process more than 2048 signals."); messagewindow.exec(); fclose(file); file = NULL; return; } fseeko(file, 0LL, SEEK_END); filesize = ftello(file); if(filesize < (((edfsignals + 1LL) * 256LL) + edfsignals)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Filesize is too small.\n" "Can not fix this file."); messagewindow.exec(); fclose(file); file = NULL; return; } if((!(strncmp(hdr + 192, "EDF+C", 5))) || (!(strncmp(hdr + 192, "EDF+D", 5)))) { edfplus = 1; } if((!(strncmp(hdr + 192, "BDF+C", 5))) || (!(strncmp(hdr + 192, "BDF+D", 5)))) { bdfplus = 1; } read_header(); } void UI_headerEditorWindow::read_header() { int i, j, p, r; char scratchpad[256], str[256]; if(file == NULL) { return; } fileNameLabel->setText(QString::fromLocal8Bit(path)); rewind(file); if(fread(hdr, (256 * edfsignals) + 256, 1, file) != 1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not read from file."); messagewindow.exec(); fclose(file); file = NULL; return; } startTimeDate->setVisible(TRUE); startTimeDateLabel->setVisible(TRUE); if(edfplus || bdfplus) { startTimeDate->setMinimumDate(QDate(1970, 1, 1)); startTimeDate->setMaximumDate(QDate(2299, 12, 31)); startTimeDate->setDate(QDate(1970, 1, 1)); } else { startTimeDate->setMinimumDate(QDate(1985, 1, 1)); startTimeDate->setMaximumDate(QDate(2084, 12, 31)); startTimeDate->setDate(QDate(1985, 1, 1)); } startTimeDate->setTime(QTime(0, 0, 0)); memcpy(scratchpad, hdr + 168, 8); scratchpad[2] = 0; scratchpad[5] = 0; scratchpad[8] = 0; r = atoi(scratchpad + 6); if(r < 85) { r += 2000; } else { r += 1900; } startTimeDate->setDate(QDate(r, atoi(scratchpad + 3), atoi(scratchpad))); startTimeDate->setMinimumDate(QDate(1985, 1, 1)); startTimeDate->setMaximumDate(QDate(2084, 12, 31)); memcpy(scratchpad, hdr + 176, 8); scratchpad[2] = 0; scratchpad[5] = 0; scratchpad[8] = 0; startTimeDate->setTime(QTime(atoi(scratchpad), atoi(scratchpad + 3), atoi(scratchpad + 6))); if(edfplus || bdfplus) { label1->setVisible(FALSE); label2->setVisible(FALSE); lineEdit1->setVisible(FALSE); lineEdit2->setVisible(FALSE); label3->setVisible(TRUE); label4->setVisible(TRUE); label5->setVisible(TRUE); label6->setVisible(TRUE); label7->setVisible(TRUE); label8->setVisible(TRUE); label9->setVisible(TRUE); label11->setVisible(TRUE); label12->setVisible(TRUE); charsleft1Label->setVisible(TRUE); charsleft2Label->setVisible(TRUE); lineEdit3->setVisible(TRUE); lineEdit4->setVisible(TRUE); lineEdit5->setVisible(TRUE); lineEdit6->setVisible(TRUE); lineEdit7->setVisible(TRUE); lineEdit8->setVisible(TRUE); lineEdit9->setVisible(TRUE); comboBox1->setVisible(TRUE); checkBox1->setVisible(TRUE); dateEdit1->setVisible(TRUE); strncpy(scratchpad, hdr + 8, 80); scratchpad[80] = 0; strcat(scratchpad, " "); p = 0; for(i=0; i<80; i++) { if(scratchpad[i] == ' ') break; } if(strncmp(scratchpad, "X ", 2)) { scratchpad[i] = 0; for(j=p; jsetText(str); } else { lineEdit3->clear(); } p = ++i; for(; i<80; i++) { if(scratchpad[i] == ' ') break; } comboBox1->setCurrentIndex(0); if(!(strncmp(scratchpad + p, "M ", 2))) { comboBox1->setCurrentIndex(1); } if(!(strncmp(scratchpad + p, "F ", 2))) { comboBox1->setCurrentIndex(2); } p = ++i; for(; i<80; i++) { if(scratchpad[i] == ' ') break; } dateEdit1->setDate(QDate(1800, 1, 1)); if(strncmp(scratchpad + p, "X ", 2)) { scratchpad[i] = 0; r = 0; if(!strncmp(scratchpad + p + 3, "JAN", 3)) r = 1; else if(!strncmp(scratchpad + p + 3, "FEB", 3)) r = 2; else if(!strncmp(scratchpad + p + 3, "MAR", 3)) r = 3; else if(!strncmp(scratchpad + p + 3, "APR", 3)) r = 4; else if(!strncmp(scratchpad + p + 3, "MAY", 3)) r = 5; else if(!strncmp(scratchpad + p + 3, "JUN", 3)) r = 6; else if(!strncmp(scratchpad + p + 3, "JUL", 3)) r = 7; else if(!strncmp(scratchpad + p + 3, "AUG", 3)) r = 8; else if(!strncmp(scratchpad + p + 3, "SEP", 3)) r = 9; else if(!strncmp(scratchpad + p + 3, "OCT", 3)) r = 10; else if(!strncmp(scratchpad + p + 3, "NOV", 3)) r = 11; else if(!strncmp(scratchpad + p + 3, "DEC", 3)) r = 12; if(r) { dateEdit1->setDate(QDate(atoi(scratchpad + p + 7), r, atoi(scratchpad + p))); checkBox1->setCheckState(Qt::Unchecked); } p += 10; } else { checkBox1->setCheckState(Qt::Checked); } p = ++i; for(; i<80; i++) { if(scratchpad[i] == ' ') break; } if(strncmp(scratchpad + p, "X ", 2)) { scratchpad[i] = 0; for(j=p; jsetText(str); } else { lineEdit4->clear(); } p = ++i; scratchpad[80] = 0; strcpy(str, scratchpad + p); remove_trailing_spaces(str); lineEdit5->setText(str); strncpy(scratchpad, hdr + 88, 80); scratchpad[80] = 0; strcat(scratchpad, " "); p = 10; for(i=10; i<80; i++) { if(scratchpad[i] == ' ') break; } if(strncmp(scratchpad + p, "X ", 2)) { scratchpad[i] = 0; has_startdate = 1; scratchpad[12] = 0; scratchpad[16] = 0; scratchpad[21] = 0; r = 0; if(!strncmp(scratchpad + 13, "JAN", 3)) r = 1; else if(!strncmp(scratchpad + 13, "FEB", 3)) r = 2; else if(!strncmp(scratchpad + 13, "MAR", 3)) r = 3; else if(!strncmp(scratchpad + 13, "APR", 3)) r = 4; else if(!strncmp(scratchpad + 13, "MAY", 3)) r = 5; else if(!strncmp(scratchpad + 13, "JUN", 3)) r = 6; else if(!strncmp(scratchpad + 13, "JUL", 3)) r = 7; else if(!strncmp(scratchpad + 13, "AUG", 3)) r = 8; else if(!strncmp(scratchpad + 13, "SEP", 3)) r = 9; else if(!strncmp(scratchpad + 13, "OCT", 3)) r = 10; else if(!strncmp(scratchpad + 13, "NOV", 3)) r = 11; else if(!strncmp(scratchpad + 13, "DEC", 3)) r = 12; if(r) { startTimeDate->setDate(QDate(atoi(scratchpad + 17), r, atoi(scratchpad + 10))); startTimeDate->setMinimumDate(QDate(1970, 1, 1)); startTimeDate->setMaximumDate(QDate(2299, 12, 31)); } } else { has_startdate = 0; } p = ++i; for(; i<80; i++) { if(scratchpad[i] == ' ') break; } if(strncmp(scratchpad + p, "X ", 2)) { scratchpad[i] = 0; for(j=p; jsetText(str); } else { lineEdit6->clear(); } p = ++i; for(; i<80; i++) { if(scratchpad[i] == ' ') break; } if(strncmp(scratchpad + p, "X ", 2)) { scratchpad[i] = 0; for(j=p; jsetText(str); } else { lineEdit7->clear(); } p = ++i; for(; i<80; i++) { if(scratchpad[i] == ' ') break; } if(strncmp(scratchpad + p, "X ", 2)) { scratchpad[i] = 0; for(j=p; jsetText(str); } else { lineEdit8->clear(); } p = ++i; scratchpad[80] = 0; strcpy(str, scratchpad + p); remove_trailing_spaces(str); lineEdit9->setText(str); calculate_chars_left_name(""); calculate_chars_left_recording(""); connect(lineEdit3, SIGNAL(textEdited(const QString &)), this, SLOT(calculate_chars_left_name(const QString &))); connect(lineEdit4, SIGNAL(textEdited(const QString &)), this, SLOT(calculate_chars_left_name(const QString &))); connect(lineEdit5, SIGNAL(textEdited(const QString &)), this, SLOT(calculate_chars_left_name(const QString &))); connect(lineEdit6, SIGNAL(textEdited(const QString &)), this, SLOT(calculate_chars_left_recording(const QString &))); connect(lineEdit7, SIGNAL(textEdited(const QString &)), this, SLOT(calculate_chars_left_recording(const QString &))); connect(lineEdit8, SIGNAL(textEdited(const QString &)), this, SLOT(calculate_chars_left_recording(const QString &))); connect(lineEdit9, SIGNAL(textEdited(const QString &)), this, SLOT(calculate_chars_left_recording(const QString &))); } else { label3->setVisible(FALSE); label4->setVisible(FALSE); label5->setVisible(FALSE); label6->setVisible(FALSE); label7->setVisible(FALSE); label8->setVisible(FALSE); label9->setVisible(FALSE); label11->setVisible(FALSE); label12->setVisible(FALSE); charsleft1Label->setVisible(FALSE); charsleft2Label->setVisible(FALSE); lineEdit3->setVisible(FALSE); lineEdit4->setVisible(FALSE); lineEdit5->setVisible(FALSE); lineEdit6->setVisible(FALSE); lineEdit7->setVisible(FALSE); lineEdit8->setVisible(FALSE); lineEdit9->setVisible(FALSE); comboBox1->setVisible(FALSE); checkBox1->setVisible(FALSE); dateEdit1->setVisible(FALSE); label1->setVisible(TRUE); label2->setVisible(TRUE); lineEdit1->setVisible(TRUE); lineEdit2->setVisible(TRUE); strncpy(scratchpad, hdr + 8, 80); scratchpad[80] = 0; remove_trailing_spaces(scratchpad); lineEdit1->setText(scratchpad); strncpy(scratchpad, hdr + 88, 80); scratchpad[80] = 0; remove_trailing_spaces(scratchpad); lineEdit2->setText(scratchpad); } datrecs = antoi(hdr + 236, 8); signallist->setRowCount(edfsignals); recordsize = 0; for(i=0; isetRowHeight(i, 25); strncpy(scratchpad, hdr + 256 + (i * 16), 16); scratchpad[16] = 0; remove_trailing_spaces(scratchpad); signallist->setCellWidget(i, 0, new QLineEdit(scratchpad)); ((QLineEdit *)(signallist->cellWidget(i, 0)))->setMaxLength(16); ((QLineEdit *)(signallist->cellWidget(i, 0)))->setText(scratchpad); strncpy(scratchpad, hdr + 256 + (edfsignals * 96) + (i * 8), 8); scratchpad[8] = 0; remove_trailing_spaces(scratchpad); signallist->setCellWidget(i, 1, new QLineEdit(scratchpad)); ((QLineEdit *)(signallist->cellWidget(i, 1)))->setMaxLength(8); ((QLineEdit *)(signallist->cellWidget(i, 1)))->setText(scratchpad); strncpy(scratchpad, hdr + 256 + (edfsignals * 136) + (i * 80), 80); scratchpad[80] = 0; remove_trailing_spaces(scratchpad); signallist->setCellWidget(i, 2, new QLineEdit(scratchpad)); ((QLineEdit *)(signallist->cellWidget(i, 2)))->setMaxLength(80); ((QLineEdit *)(signallist->cellWidget(i, 2)))->setText(scratchpad); strncpy(scratchpad, hdr + 256 + (edfsignals * 16) + (i * 80), 80); scratchpad[80] = 0; remove_trailing_spaces(scratchpad); signallist->setCellWidget(i, 3, new QLineEdit(scratchpad)); ((QLineEdit *)(signallist->cellWidget(i, 3)))->setMaxLength(80); ((QLineEdit *)(signallist->cellWidget(i, 3)))->setText(scratchpad); strncpy(scratchpad, hdr + 256 + (edfsignals * 216) + (i * 8), 8); scratchpad[8] = 0; if(atoi(scratchpad) < 1) { sprintf(str, "Samples per record of signal %i is less than 1.\n" "Can not fix this file.", i + 1); QMessageBox messagewindow(QMessageBox::Critical, "Error", str); messagewindow.exec(); fclose(file); file = NULL; return; } if(bdf) { recordsize += (atoi(scratchpad) * 3); } else { recordsize += (atoi(scratchpad) * 2); } if(edfplus) { if(!(strncmp(((QLineEdit *)(signallist->cellWidget(i, 0)))->text().toLatin1().data(), "EDF Annotations", 15))) { ((QLineEdit *)(signallist->cellWidget(i, 0)))->setEnabled(FALSE); ((QLineEdit *)(signallist->cellWidget(i, 1)))->setEnabled(FALSE); ((QLineEdit *)(signallist->cellWidget(i, 2)))->setEnabled(FALSE); ((QLineEdit *)(signallist->cellWidget(i, 3)))->setEnabled(FALSE); } } if(bdfplus) { if(!(strncmp(((QLineEdit *)(signallist->cellWidget(i, 0)))->text().toLatin1().data(), "BDF Annotations", 15))) { ((QLineEdit *)(signallist->cellWidget(i, 0)))->setEnabled(FALSE); ((QLineEdit *)(signallist->cellWidget(i, 1)))->setEnabled(FALSE); ((QLineEdit *)(signallist->cellWidget(i, 2)))->setEnabled(FALSE); ((QLineEdit *)(signallist->cellWidget(i, 3)))->setEnabled(FALSE); } } } if(recordsize < 1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Recordsize is less than 1.\n" "Can not fix this file."); messagewindow.exec(); fclose(file); file = NULL; return; } } void UI_headerEditorWindow::save_hdr() { int i, j, p, len, hassign; char scratchpad[256], str[256]; long long filesize, l_tmp=0LL; if(file == NULL) { return; } sprintf(scratchpad, "%02i.%02i.%02i%02i.%02i.%02i", startTimeDate->date().day(), startTimeDate->date().month(), startTimeDate->date().year() % 100, startTimeDate->time().hour(), startTimeDate->time().minute(), startTimeDate->time().second()); fseeko(file, 168LL, SEEK_SET); fprintf(file, "%s", scratchpad); if(edfplus || bdfplus) { str[0] = 0; len = strlen(lineEdit3->text().toLatin1().data()); // patient code if(len) { strcpy(scratchpad, lineEdit3->text().toLatin1().data()); latin1_to_ascii(scratchpad, len); remove_trailing_spaces(scratchpad); for(i=0; icurrentIndex() == 0) // gender { strcat(str, "X "); } if(comboBox1->currentIndex() == 1) { strcat(str, "M "); } if(comboBox1->currentIndex() == 2) { strcat(str, "F "); } if(checkBox1->checkState() == Qt::Checked) // birthdate { strcat(str, "X "); } else { i = dateEdit1->date().month(); switch(i) { case 1 : sprintf(scratchpad, "%02i-JAN-%04i ", dateEdit1->date().day(), dateEdit1->date().year()); break; case 2 : sprintf(scratchpad, "%02i-FEB-%04i ", dateEdit1->date().day(), dateEdit1->date().year()); break; case 3 : sprintf(scratchpad, "%02i-MAR-%04i ", dateEdit1->date().day(), dateEdit1->date().year()); break; case 4 : sprintf(scratchpad, "%02i-APR-%04i ", dateEdit1->date().day(), dateEdit1->date().year()); break; case 5 : sprintf(scratchpad, "%02i-MAY-%04i ", dateEdit1->date().day(), dateEdit1->date().year()); break; case 6 : sprintf(scratchpad, "%02i-JUN-%04i ", dateEdit1->date().day(), dateEdit1->date().year()); break; case 7 : sprintf(scratchpad, "%02i-JUL-%04i ", dateEdit1->date().day(), dateEdit1->date().year()); break; case 8 : sprintf(scratchpad, "%02i-AUG-%04i ", dateEdit1->date().day(), dateEdit1->date().year()); break; case 9 : sprintf(scratchpad, "%02i-SEP-%04i ", dateEdit1->date().day(), dateEdit1->date().year()); break; case 10 : sprintf(scratchpad, "%02i-OCT-%04i ", dateEdit1->date().day(), dateEdit1->date().year()); break; case 11 : sprintf(scratchpad, "%02i-NOV-%04i ", dateEdit1->date().day(), dateEdit1->date().year()); break; case 12 : sprintf(scratchpad, "%02i-DEC-%04i ", dateEdit1->date().day(), dateEdit1->date().year()); break; } strcat(str, scratchpad); } len = strlen(lineEdit4->text().toLatin1().data()); // patient name if(len) { strcpy(scratchpad, lineEdit4->text().toLatin1().data()); latin1_to_ascii(scratchpad, len); remove_trailing_spaces(scratchpad); for(i=0; itext().toLatin1().data()); // additional info if(len) { strcpy(scratchpad, lineEdit5->text().toLatin1().data()); latin1_to_ascii(scratchpad, len); remove_trailing_spaces(scratchpad); strcat(str, scratchpad); } for(i=0; i<8; i++) { strcat(str, " "); } str[80] = 0; fseeko(file, 8LL, SEEK_SET); fprintf(file, "%s", str); if(has_startdate) { strcpy(str, "Startdate "); i = startTimeDate->date().month(); switch(i) { case 1 : sprintf(scratchpad, "%02i-JAN-%04i ", startTimeDate->date().day(), startTimeDate->date().year()); break; case 2 : sprintf(scratchpad, "%02i-FEB-%04i ", startTimeDate->date().day(), startTimeDate->date().year()); break; case 3 : sprintf(scratchpad, "%02i-MAR-%04i ", startTimeDate->date().day(), startTimeDate->date().year()); break; case 4 : sprintf(scratchpad, "%02i-APR-%04i ", startTimeDate->date().day(), startTimeDate->date().year()); break; case 5 : sprintf(scratchpad, "%02i-MAY-%04i ", startTimeDate->date().day(), startTimeDate->date().year()); break; case 6 : sprintf(scratchpad, "%02i-JUN-%04i ", startTimeDate->date().day(), startTimeDate->date().year()); break; case 7 : sprintf(scratchpad, "%02i-JUL-%04i ", startTimeDate->date().day(), startTimeDate->date().year()); break; case 8 : sprintf(scratchpad, "%02i-AUG-%04i ", startTimeDate->date().day(), startTimeDate->date().year()); break; case 9 : sprintf(scratchpad, "%02i-SEP-%04i ", startTimeDate->date().day(), startTimeDate->date().year()); break; case 10 : sprintf(scratchpad, "%02i-OCT-%04i ", startTimeDate->date().day(), startTimeDate->date().year()); break; case 11 : sprintf(scratchpad, "%02i-NOV-%04i ", startTimeDate->date().day(), startTimeDate->date().year()); break; case 12 : sprintf(scratchpad, "%02i-DEC-%04i ", startTimeDate->date().day(), startTimeDate->date().year()); break; } strcat(str, scratchpad); } else { strcpy(str, "Startdate X "); } len = strlen(lineEdit6->text().toLatin1().data()); // administration code if(len) { strcpy(scratchpad, lineEdit6->text().toLatin1().data()); latin1_to_ascii(scratchpad, len); remove_trailing_spaces(scratchpad); for(i=0; itext().toLatin1().data()); // technician if(len) { strcpy(scratchpad, lineEdit7->text().toLatin1().data()); latin1_to_ascii(scratchpad, len); remove_trailing_spaces(scratchpad); for(i=0; itext().toLatin1().data()); // device if(len) { strcpy(scratchpad, lineEdit8->text().toLatin1().data()); latin1_to_ascii(scratchpad, len); remove_trailing_spaces(scratchpad); for(i=0; itext().toLatin1().data()); // additional info if(len) { strcpy(scratchpad, lineEdit9->text().toLatin1().data()); latin1_to_ascii(scratchpad, len); remove_trailing_spaces(scratchpad); strcat(str, scratchpad); } for(i=0; i<8; i++) { strcat(str, " "); } str[80] = 0; fseeko(file, 88LL, SEEK_SET); fprintf(file, "%s", str); } else { strcpy(scratchpad, lineEdit1->text().toLatin1().data()); for(j=strlen(scratchpad); j<80; j++) { scratchpad[j] = ' '; } latin1_to_ascii(scratchpad, 80); scratchpad[80] = 0; fseeko(file, 8LL, SEEK_SET); fprintf(file, "%s", scratchpad); strcpy(scratchpad, lineEdit2->text().toLatin1().data()); for(j=strlen(scratchpad); j<80; j++) { scratchpad[j] = ' '; } latin1_to_ascii(scratchpad, 80); scratchpad[80] = 0; fseeko(file, 88LL, SEEK_SET); fprintf(file, "%s", scratchpad); } fseeko(file, 170LL, SEEK_SET); fputc('.', file); fseeko(file, 173LL, SEEK_SET); fputc('.', file); fseeko(file, 178LL, SEEK_SET); fputc('.', file); fseeko(file, 181LL, SEEK_SET); fputc('.', file); if(edfplus || bdfplus) // reserved { fseeko(file, 197LL, SEEK_SET); for(j=0; j<39; j++) { fputc(' ', file); } } else { fseeko(file, 192LL, SEEK_SET); for(j=0; j<44; j++) { fputc(' ', file); } } for(i=0; icellWidget(i, 0)))->isEnabled() == FALSE) // EDF/BDF Annotations signal { fseeko(file, (long long)(256 + (edfsignals * 96) + (i * 8)), SEEK_SET); // physical dimension fprintf(file, " "); for(j=0; j<80; j++) { scratchpad[j] = ' '; } scratchpad[80] = 0; fseeko(file, (long long)(256 + (edfsignals * 136) + (i * 80)), SEEK_SET); // prefiltering fprintf(file, "%s", scratchpad); for(j=0; j<80; j++) { scratchpad[j] = ' '; } scratchpad[80] = 0; fseeko(file, (long long)(256 + (edfsignals * 16) + (i * 80)), SEEK_SET); // transducer type fprintf(file, "%s", scratchpad); fseeko(file, (long long)(256 + (edfsignals * 120) + (i * 8)), SEEK_SET); // digital minimum if(edfplus) { fprintf(file, "-32768 "); } else { if(bdfplus) { fprintf(file, "-8388608"); } } fseeko(file, (long long)(256 + (edfsignals * 128) + (i * 8)), SEEK_SET); // digital maximum if(edfplus) { fprintf(file, "32767 "); } else { if(bdfplus) { fprintf(file, "8388607 "); } } fseeko(file, (long long)(256 + (edfsignals * 104) + (i * 8)), SEEK_SET); // physical minimum fprintf(file, "-1 "); fseeko(file, (long long)(256 + (edfsignals * 112) + (i * 8)), SEEK_SET); // physical maximum fprintf(file, "1 "); } else { strcpy(scratchpad, ((QLineEdit *)(signallist->cellWidget(i, 0)))->text().toLatin1().data()); for(j=strlen(scratchpad); j<16; j++) { scratchpad[j] = ' '; } latin1_to_ascii(scratchpad, 16); scratchpad[16] = 0; fseeko(file, (long long)(256 + (i * 16)), SEEK_SET); fprintf(file, "%s", scratchpad); strcpy(scratchpad, ((QLineEdit *)(signallist->cellWidget(i, 1)))->text().toLatin1().data()); for(j=strlen(scratchpad); j<8; j++) { scratchpad[j] = ' '; } latin1_to_ascii(scratchpad, 8); scratchpad[8] = 0; fseeko(file, (long long)(256 + (edfsignals * 96) + (i * 8)), SEEK_SET); fprintf(file, "%s", scratchpad); strcpy(scratchpad, ((QLineEdit *)(signallist->cellWidget(i, 2)))->text().toLatin1().data()); for(j=strlen(scratchpad); j<80; j++) { scratchpad[j] = ' '; } latin1_to_ascii(scratchpad, 80); scratchpad[80] = 0; fseeko(file, (long long)(256 + (edfsignals * 136) + (i * 80)), SEEK_SET); fprintf(file, "%s", scratchpad); strcpy(scratchpad, ((QLineEdit *)(signallist->cellWidget(i, 3)))->text().toLatin1().data()); for(j=strlen(scratchpad); j<80; j++) { scratchpad[j] = ' '; } latin1_to_ascii(scratchpad, 80); scratchpad[80] = 0; fseeko(file, (long long)(256 + (edfsignals * 16) + (i * 80)), SEEK_SET); fprintf(file, "%s", scratchpad); strncpy(scratchpad, hdr + 256 + (edfsignals * 120) + (i * 8), 8); // digital minimum hassign = 0; p = 0; if((scratchpad[0] == '+') || (scratchpad[0] == '-')) { hassign = 1; p++; } for(; p<8; p++) { if((scratchpad[p] < '0') || (scratchpad[p] > '9')) { break; } } if(p != hassign) { for(; p<8; p++) { scratchpad[p] = ' '; } scratchpad[8] = 0; fseeko(file, (long long)(256 + (edfsignals * 120) + (i * 8)), SEEK_SET); fprintf(file, "%s", scratchpad); } strncpy(scratchpad, hdr + 256 + (edfsignals * 128) + (i * 8), 8); // digital maximum hassign = 0; p = 0; if((scratchpad[0] == '+') || (scratchpad[0] == '-')) { hassign = 1; p++; } for(; p<8; p++) { if((scratchpad[p] < '0') || (scratchpad[p] > '9')) { break; } } if(p != hassign) { for(; p<8; p++) { scratchpad[p] = ' '; } scratchpad[8] = 0; fseeko(file, (long long)(256 + (edfsignals * 128) + (i * 8)), SEEK_SET); fprintf(file, "%s", scratchpad); } strncpy(scratchpad, hdr + 256 + (edfsignals * 104) + (i * 8), 8); // physical minimum for(p=7; p>0; p--) { if((scratchpad[p] < '0') || (scratchpad[p] > '9')) { scratchpad[p] = ' '; } else { break; } } scratchpad[8] = 0; fseeko(file, (long long)(256 + (edfsignals * 104) + (i * 8)), SEEK_SET); fprintf(file, "%s", scratchpad); strncpy(scratchpad, hdr + 256 + (edfsignals * 112) + (i * 8), 8); // physical maximum for(p=7; p>0; p--) { if((scratchpad[p] < '0') || (scratchpad[p] > '9')) { scratchpad[p] = ' '; } else { break; } } scratchpad[8] = 0; fseeko(file, (long long)(256 + (edfsignals * 112) + (i * 8)), SEEK_SET); fprintf(file, "%s", scratchpad); } fseeko(file, (long long)(256 + (edfsignals * 224) + (i * 32)), SEEK_SET); // reserved for(j=0; j<32; j++) { fputc(' ', file); } } fseeko(file, 236LL, SEEK_SET); fprintf(file, "%-8i", datrecs); // datarecords fseeko(file, 0LL, SEEK_END); filesize = ftello(file); if(filesize != (((long long)recordsize * (long long)datrecs)) + ((edfsignals * 256) + 256)) { l_tmp = filesize - ((edfsignals * 256) + 256); datrecs = l_tmp / (long long)recordsize; if(datrecs > 0) { if(datrecs > 99999999) { datrecs = 99999999; } fseeko(file, 236LL, SEEK_SET); fprintf(file, "%-8i", datrecs); l_tmp = ((edfsignals * 256) + 256); l_tmp += (long long)datrecs * (long long)recordsize; if(l_tmp != filesize) { fclose(file); if(QFile::resize(QString::fromLocal8Bit(path), l_tmp) == FALSE) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not resize file."); messagewindow.exec(); } file = fopeno(path, "r+b"); if(file==NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not open file."); messagewindow.exec(); return; } } } } fflush(file); read_header(); } void UI_headerEditorWindow::calculate_chars_left_name(const QString &) { int n = 61; int len; int cursorposition[3]; char str[128]; cursorposition[0] = lineEdit3->cursorPosition(); cursorposition[1] = lineEdit4->cursorPosition(); cursorposition[2] = lineEdit5->cursorPosition(); len = strlen(lineEdit3->text().toLatin1().data()); if(len>1) { n -= (len - 1); } len = strlen(lineEdit4->text().toLatin1().data()); if(len>1) { n -= (len - 1); } len = strlen(lineEdit5->text().toLatin1().data()); if(len>1) { n -= (len - 1); } if(n<1) { lineEdit3->setMaxLength(strlen(lineEdit3->text().toLatin1().data())); lineEdit4->setMaxLength(strlen(lineEdit4->text().toLatin1().data())); lineEdit5->setMaxLength(strlen(lineEdit5->text().toLatin1().data())); } else { lineEdit3->setMaxLength(80); lineEdit4->setMaxLength(80); lineEdit5->setMaxLength(80); } lineEdit3->setCursorPosition(cursorposition[0]); lineEdit4->setCursorPosition(cursorposition[1]); lineEdit5->setCursorPosition(cursorposition[2]); sprintf(str, "Characters left: %i", n); charsleft1Label->setText(str); } void UI_headerEditorWindow::calculate_chars_left_recording(const QString &) { int n = 42; int len; int cursorposition[4]; char str[128]; cursorposition[0] = lineEdit6->cursorPosition(); cursorposition[1] = lineEdit7->cursorPosition(); cursorposition[2] = lineEdit8->cursorPosition(); cursorposition[3] = lineEdit9->cursorPosition(); len = strlen(lineEdit6->text().toLatin1().data()); if(len>1) { n -= (len - 1); } len = strlen(lineEdit7->text().toLatin1().data()); if(len>1) { n -= (len - 1); } len = strlen(lineEdit8->text().toLatin1().data()); if(len>1) { n -= (len - 1); } len = strlen(lineEdit9->text().toLatin1().data()); if(len>1) { n -= (len - 1); } if(n<1) { lineEdit6->setMaxLength(strlen(lineEdit6->text().toLatin1().data())); lineEdit7->setMaxLength(strlen(lineEdit7->text().toLatin1().data())); lineEdit8->setMaxLength(strlen(lineEdit8->text().toLatin1().data())); lineEdit9->setMaxLength(strlen(lineEdit9->text().toLatin1().data())); } else { lineEdit6->setMaxLength(80); lineEdit7->setMaxLength(80); lineEdit8->setMaxLength(80); lineEdit9->setMaxLength(80); } lineEdit6->setCursorPosition(cursorposition[0]); lineEdit7->setCursorPosition(cursorposition[1]); lineEdit8->setCursorPosition(cursorposition[2]); lineEdit9->setCursorPosition(cursorposition[3]); sprintf(str, "Characters left: %i", n); charsleft2Label->setText(str); } edfbrowser_153_source/PaxHeaders.2978/export_annotations.cpp0000644000175000001440000000013212251654530022611 xustar000000000000000030 mtime=1386699096.477032522 30 atime=1386699096.477032522 30 ctime=1386699096.477032522 edfbrowser_153_source/export_annotations.cpp0000644000175000001440000005544712251654530022361 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "export_annotations.h" #if defined(__APPLE__) || defined(__MACH__) || defined(__APPLE_CC__) #define fopeno fopen #else #define fseeko fseeko64 #define ftello ftello64 #define fopeno fopen64 #endif UI_ExportAnnotationswindow::UI_ExportAnnotationswindow(QWidget *w_parent) { int i; mainwindow = (UI_Mainwindow *)w_parent; ExportAnnotsDialog = new QDialog; ExportAnnotsDialog->setMinimumSize(QSize(800, 570)); ExportAnnotsDialog->setMaximumSize(QSize(800, 570)); ExportAnnotsDialog->setWindowTitle("Export annotations"); ExportAnnotsDialog->setModal(TRUE); ExportAnnotsDialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); filelist = new QListWidget(ExportAnnotsDialog); filelist->setGeometry(QRect(10, 10, 780, 75)); filelist->setSelectionBehavior(QAbstractItemView::SelectRows); filelist->setSelectionMode(QAbstractItemView::SingleSelection); for(i=0; ifiles_open; i++) { new QListWidgetItem(QString::fromLocal8Bit(mainwindow->edfheaderlist[i]->filename), filelist); } formatGroupBox = new QGroupBox("output format", ExportAnnotsDialog); formatGroupBox->setGeometry(10, 120, 200, 135); CSVRadioButton = new QRadioButton("ASCII/CSV"); EDFplusRadioButton = new QRadioButton("EDFplus"); XMLRadioButton = new QRadioButton("XML"); formatVBoxLayout = new QVBoxLayout; formatVBoxLayout->addWidget(CSVRadioButton); formatVBoxLayout->addWidget(EDFplusRadioButton); formatVBoxLayout->addWidget(XMLRadioButton); formatGroupBox->setLayout(formatVBoxLayout); fileGroupBox = new QGroupBox("export annotations", ExportAnnotsDialog); fileGroupBox->setGeometry(320, 120, 200, 90); selectRadioButton = new QRadioButton("from selected file"); selectRadioButton->setChecked(TRUE); mergeRadioButton = new QRadioButton("from all files (merge)"); fileVBoxLayout = new QVBoxLayout; fileVBoxLayout->addWidget(selectRadioButton); fileVBoxLayout->addWidget(mergeRadioButton); fileGroupBox->setLayout(fileVBoxLayout); asciiSettingsGroupBox = new QGroupBox("ASCII settings", ExportAnnotsDialog); asciiSettingsGroupBox->setGeometry(10, 270, 300, 290); separatorLabel = new QLabel(ExportAnnotsDialog); separatorLabel->setText("separator:"); separatorBox = new QComboBox(ExportAnnotsDialog); separatorBox->addItem("comma"); separatorBox->addItem("tab"); asciiSecondsRadioButton = new QRadioButton("seconds relative to start of file"); asciiSecondsRadioButton->setChecked(TRUE); asciiISOtimeRadioButton = new QRadioButton("ISO timestamp hh:mm:ss"); asciiISOtimedateRadioButton = new QRadioButton("ISO datetimestamp yyyy-mm-ddThh:mm:ss"); asciiISOtimeFractionRadioButton = new QRadioButton("ISO timestamp hh:mm:ss.xxx"); asciiISOtimedateFractionRadioButton = new QRadioButton("ISO datetimestamp yyyy-mm-ddThh:mm:ss.xxx"); durationCheckBox = new QCheckBox("include duration", ExportAnnotsDialog); durationCheckBox->setTristate(FALSE); durationCheckBox->setCheckState(Qt::Unchecked); asciiSettingsHBoxLayout = new QHBoxLayout; asciiSettingsHBoxLayout->addWidget(separatorLabel); asciiSettingsHBoxLayout->addWidget(separatorBox); asciiSettingsVBoxLayout = new QVBoxLayout; asciiSettingsVBoxLayout->addLayout(asciiSettingsHBoxLayout); asciiSettingsVBoxLayout->addWidget(asciiSecondsRadioButton); asciiSettingsVBoxLayout->addWidget(asciiISOtimeRadioButton); asciiSettingsVBoxLayout->addWidget(asciiISOtimedateRadioButton); asciiSettingsVBoxLayout->addWidget(asciiISOtimeFractionRadioButton); asciiSettingsVBoxLayout->addWidget(asciiISOtimedateFractionRadioButton); asciiSettingsVBoxLayout->addWidget(durationCheckBox); asciiSettingsGroupBox->setLayout(asciiSettingsVBoxLayout); ExportButton = new QPushButton(ExportAnnotsDialog); ExportButton->setGeometry(QRect(500, 530, 100, 25)); ExportButton->setText("Export"); CloseButton = new QPushButton(ExportAnnotsDialog); CloseButton->setGeometry(QRect(690, 530, 100, 25)); CloseButton->setText("Close"); separatorBox->setCurrentIndex(mainwindow->export_annotations_var->separator); switch(mainwindow->export_annotations_var->format) { case 0 : EDFplusRadioButton->setChecked(TRUE); asciiSettingsGroupBox->setEnabled(FALSE); break; case 8 : XMLRadioButton->setChecked(TRUE); asciiSettingsGroupBox->setEnabled(FALSE); break; case 1 : CSVRadioButton->setChecked(TRUE); asciiSettingsGroupBox->setEnabled(TRUE); asciiSecondsRadioButton->setChecked(TRUE); break; case 2 : CSVRadioButton->setChecked(TRUE); asciiSettingsGroupBox->setEnabled(TRUE); asciiISOtimeRadioButton->setChecked(TRUE); break; case 3 : CSVRadioButton->setChecked(TRUE); asciiSettingsGroupBox->setEnabled(TRUE); asciiISOtimedateRadioButton->setChecked(TRUE); break; case 4 : CSVRadioButton->setChecked(TRUE); asciiSettingsGroupBox->setEnabled(TRUE); asciiISOtimeFractionRadioButton->setChecked(TRUE); break; case 5 : CSVRadioButton->setChecked(TRUE); asciiSettingsGroupBox->setEnabled(TRUE); asciiISOtimedateFractionRadioButton->setChecked(TRUE); break; } if(mainwindow->export_annotations_var->duration) { durationCheckBox->setChecked(TRUE); } else { durationCheckBox->setChecked(FALSE); } QObject::connect(CloseButton, SIGNAL(clicked()), ExportAnnotsDialog, SLOT(close())); QObject::connect(ExportButton, SIGNAL(clicked()), this, SLOT(ExportButtonClicked())); QObject::connect(CSVRadioButton, SIGNAL(toggled(bool)), this, SLOT(outputformatRadioButtonClicked(bool))); filelist->setCurrentRow(mainwindow->files_open - 1); ExportAnnotsDialog->exec(); } void UI_ExportAnnotationswindow::outputformatRadioButtonClicked(bool checked) { if(checked == TRUE) { asciiSettingsGroupBox->setEnabled(TRUE); } else { asciiSettingsGroupBox->setEnabled(FALSE); } } 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; ifiles_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; ionset - 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, "\n"); fprintf(annotationfile, "\n"); fprintf(annotationfile, "\n"); utc_to_date_time(hdr->utc_starttime, &tm); fprintf(annotationfile, " %04i-%02i-%02iT%02i:%02i:%02i.%07i\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, " \n" " %04i-%02i-%02iT%02i:%02i:%02i.%07i\n" " %s\n" " ", tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second, temp, annot->duration); xml_fwrite_encode_entity(annotationfile, annot->annotation); fprintf(annotationfile, "\n" " \n"); } fprintf(annotationfile, "\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; ionset / 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(); } } edfbrowser_153_source/PaxHeaders.2978/filteredblockread.cpp0000644000175000001440000000013212251654530022320 xustar000000000000000030 mtime=1386699096.477032522 30 atime=1386699096.477032522 30 ctime=1386699096.477032522 edfbrowser_153_source/filteredblockread.cpp0000644000175000001440000001417012251654530022054 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "filteredblockread.h" #if defined(__APPLE__) || defined(__MACH__) || defined(__APPLE_CC__) #define fopeno fopen #else #define fseeko fseeko64 #define ftello ftello64 #define fopeno fopen64 #endif double * FilteredBlockReadClass::init_signalcomp(struct signalcompblock *i_signalcomp, int i_datarecord_cnt, int skip_f) { skip_filters = skip_f; if(i_signalcomp == NULL) { datarecord_cnt = -1; total_samples = -1; return(NULL); } signalcomp = i_signalcomp; hdr = signalcomp->edfhdr; if(hdr == NULL) { datarecord_cnt = -1; total_samples = -1; return(NULL); } inputfile = hdr->file_hdl; if(inputfile == NULL) { datarecord_cnt = -1; total_samples = -1; return(NULL); } datarecord_cnt = i_datarecord_cnt; if((datarecord_cnt > hdr->datarecords) || (datarecord_cnt < 1)) { datarecord_cnt = -1; total_samples = -1; return(NULL); } samples_per_datrec = hdr->edfparam[signalcomp->edfsignal[0]].smp_per_record; total_samples = samples_per_datrec * datarecord_cnt; if(processed_samples_buf != NULL) { free(processed_samples_buf); } processed_samples_buf = (double *)malloc(total_samples * sizeof(double)); if(processed_samples_buf == NULL) { datarecord_cnt = -1; total_samples = -1; return(NULL); } if(readbuf != NULL) { free(readbuf); } readbuf = (char *)malloc(hdr->recordsize * datarecord_cnt); if(readbuf == NULL) { datarecord_cnt = -1; total_samples = -1; free(processed_samples_buf); processed_samples_buf = NULL; return(NULL); } bitvalue = signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].bitvalue; return(processed_samples_buf); } int FilteredBlockReadClass::samples_in_buf(void) { return(total_samples); } FilteredBlockReadClass::FilteredBlockReadClass() { readbuf = NULL; processed_samples_buf = NULL; datarecord_cnt = -1; total_samples = -1; inputfile = NULL; hdr = NULL; signalcomp = NULL; } FilteredBlockReadClass::~FilteredBlockReadClass() { if(processed_samples_buf != NULL) { free(processed_samples_buf); } if(readbuf != NULL) { free(readbuf); } } int FilteredBlockReadClass::process_signalcomp(int datarecord_start) { int j, k, s; double dig_value=0.0, f_tmp=0.0; union { unsigned int one; signed int one_signed; unsigned short two[2]; signed short two_signed[2]; unsigned char four[4]; } var; if((total_samples < 1) || (datarecord_cnt < 1)) { return(-1); } if((datarecord_start < 0) || (datarecord_start >= hdr->datarecords)) { return(-1); } if(datarecord_cnt > (hdr->datarecords - datarecord_start)) { return(-1); } if(fseeko(inputfile, ((long long)hdr->hdrsize) + (((long long)datarecord_start) * ((long long) hdr->recordsize)), SEEK_SET) == -1LL) { return(-1); } if(fread(readbuf, hdr->recordsize * datarecord_cnt, 1, inputfile) != 1) { return(-1); } if((readbuf == NULL) || (processed_samples_buf == NULL)) { return(-1); } for(s=0; snum_of_signals; j++) { if(signalcomp->edfhdr->bdf) { var.two[0] = *((unsigned short *)( readbuf + (signalcomp->edfhdr->recordsize * (s / samples_per_datrec)) + signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].buf_offset + ((s % samples_per_datrec) * 3))); var.four[2] = *((unsigned char *)( readbuf + (signalcomp->edfhdr->recordsize * (s / samples_per_datrec)) + signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].buf_offset + ((s % samples_per_datrec) * 3) + 2)); if(var.four[2]&0x80) { var.four[3] = 0xff; } else { var.four[3] = 0x00; } f_tmp = var.one_signed; } if(signalcomp->edfhdr->edf) { f_tmp = *(((short *)( readbuf + (signalcomp->edfhdr->recordsize * (s / samples_per_datrec)) + signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].buf_offset)) + (s % samples_per_datrec)); } f_tmp += signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].offset; f_tmp *= signalcomp->factor[j]; dig_value += f_tmp; } if(!skip_filters) { for(k=0; kfilter_cnt; k++) { dig_value = first_order_filter(dig_value, signalcomp->filter[k]); } for(k=0; kravg_filter_cnt; k++) { dig_value = run_ravg_filter(dig_value, signalcomp->ravg_filter[k]); } for(k=0; kfidfilter_cnt; k++) { dig_value = signalcomp->fidfuncp[k](signalcomp->fidbuf[k], dig_value); } if(signalcomp->ecg_filter != NULL) { dig_value = run_ecg_filter(dig_value, signalcomp->ecg_filter); } } processed_samples_buf[s] = (dig_value * bitvalue); } return(0); } edfbrowser_153_source/PaxHeaders.2978/nexfin2edf.cpp0000644000175000001440000000013212251654530020703 xustar000000000000000030 mtime=1386699096.478032517 30 atime=1386699096.478032517 30 ctime=1386699096.478032517 edfbrowser_153_source/nexfin2edf.cpp0000644000175000001440000005426212251654530020445 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "nexfin2edf.h" #if defined(__APPLE__) || defined(__MACH__) || defined(__APPLE_CC__) #define fopeno fopen #else #define fseeko fseeko64 #define ftello ftello64 #define fopeno fopen64 #endif UI_NEXFIN2EDFwindow::UI_NEXFIN2EDFwindow(char *recent_dir, char *save_dir) { recent_opendir = recent_dir; recent_savedir = save_dir; myobjectDialog = new QDialog; myobjectDialog->setMinimumSize(QSize(600, 280)); myobjectDialog->setMaximumSize(QSize(600, 280)); myobjectDialog->setWindowTitle("Nexfin to EDF converter"); myobjectDialog->setModal(TRUE); myobjectDialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); PatientnameLabel = new QLabel(myobjectDialog); PatientnameLabel->setGeometry(QRect(20, 20, 140, 16)); PatientnameLabel->setText("Subject name"); RecordingLabel = new QLabel(myobjectDialog); RecordingLabel->setGeometry(QRect(20, 50, 140, 16)); RecordingLabel->setText("Recording"); DatetimeLabel = new QLabel(myobjectDialog); DatetimeLabel->setGeometry(QRect(20, 80, 140, 16)); DatetimeLabel->setText("Startdate and time"); PatientnameLineEdit = new QLineEdit(myobjectDialog); PatientnameLineEdit->setGeometry(QRect(160, 20, 420, 21)); PatientnameLineEdit->setMaxLength(80); RecordingLineEdit = new QLineEdit(myobjectDialog); RecordingLineEdit->setGeometry(QRect(160, 50, 420, 21)); RecordingLineEdit->setMaxLength(80); RecordingLineEdit->setText("Nexfin"); StartDatetimeedit = new QDateTimeEdit(myobjectDialog); StartDatetimeedit->setGeometry(QRect(160, 80, 140, 22)); StartDatetimeedit->setDisplayFormat("dd/MM/yyyy hh:mm:ss"); StartDatetimeedit->setDateTime(QDateTime::currentDateTime()); pushButton1 = new QPushButton(myobjectDialog); pushButton1->setGeometry(QRect(20, 230, 100, 26)); pushButton1->setText("Select File"); pushButton2 = new QPushButton(myobjectDialog); pushButton2->setGeometry(QRect(480, 230, 100, 26)); pushButton2->setText("Close"); radio100button = new QRadioButton(myobjectDialog); radio100button->setGeometry(QRect(160, 130, 200, 20)); radio100button->setText("Beat-to-beat data"); radio100button->setChecked(TRUE); radio103button = new QRadioButton(myobjectDialog); radio103button->setGeometry(QRect(160, 160, 200, 20)); radio103button->setText("Blood pressure waveform"); radio032button = new QRadioButton(myobjectDialog); radio032button->setGeometry(QRect(160, 190, 200, 20)); radio032button->setText("Analog inputs"); analoginputscombobox = new QComboBox(myobjectDialog); analoginputscombobox->setGeometry(QRect(280, 190, 80, 20)); analoginputscombobox->addItem("1 input"); analoginputscombobox->addItem("4 inputs"); analoginputscombobox->setCurrentIndex(1); analoginputscombobox->setEnabled(FALSE); QObject::connect(pushButton1, SIGNAL(clicked()), this, SLOT(SelectFileButton())); QObject::connect(pushButton2, SIGNAL(clicked()), myobjectDialog, SLOT(close())); QObject::connect(radio032button, SIGNAL(toggled(bool)), this, SLOT(radiobuttonchecked(bool))); myobjectDialog->exec(); } void UI_NEXFIN2EDFwindow::SelectFileButton() { FILE *inputfile=NULL, *outputfile=NULL; int i, j, k, p, temp, separator=';', edfsignals=0, ok, timestep, new_smpl_time=0, str_start, column, line_nr; long long datarecords=-1LL, file_size; char txt_string[2048], path[512], outputfilename[MAX_PATH_LENGTH], line[2048], scratchpad[128], labels[MAX_SIGNALS][17], phys_dim[MAX_SIGNALS][9], phys_min[MAX_SIGNALS][9], phys_max[MAX_SIGNALS][9], patientname[81], recording[81], datetime[17]; double sensitivity[MAX_SIGNALS], new_value[MAX_SIGNALS], old_value[MAX_SIGNALS]; union{ short two; char one[2]; } var; if(radio100button->isChecked()==TRUE) { file_type = 100; } if(radio103button->isChecked()==TRUE) { file_type = 103; } if(radio032button->isChecked()==TRUE) { file_type = 32; } for(j=0; jtext().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 recordingdescription."); messagewindow.exec(); enable_widgets(TRUE); return; } if(file_type==100) { strcpy(path, QFileDialog::getOpenFileName(0, "Select inputfile", QString::fromLocal8Bit(recent_opendir), "CSV files (*_100.csv *_100.CSV)").toLocal8Bit().data()); } if(file_type==103) { strcpy(path, QFileDialog::getOpenFileName(0, "Select inputfile", QString::fromLocal8Bit(recent_opendir), "BIN files (*_103.bin *_103.BIN)").toLocal8Bit().data()); } if(file_type==32) { strcpy(path, QFileDialog::getOpenFileName(0, "Select inputfile", QString::fromLocal8Bit(recent_opendir), "BIN files (*_032.bin *_032.BIN)").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) { snprintf(txt_string, 2048, "Can not open file %s for reading.", path); QMessageBox messagewindow(QMessageBox::Critical, "Error", QString::fromLocal8Bit(txt_string)); messagewindow.exec(); enable_widgets(TRUE); return; } if(file_type==100) { /***************** check if the txtfile is valid ******************************/ rewind(inputfile); if(fread(scratchpad, 32, 1, inputfile)!=1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not read from file."); messagewindow.exec(); fclose(inputfile); enable_widgets(TRUE); return; } if(strncmp(scratchpad, "Time;IBI;HR;LVET;HRS;Sys;Dia;MAP", 32)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Unknown data in file (1)."); messagewindow.exec(); fclose(inputfile); enable_widgets(TRUE); return; } /***************** collect items *****************************************/ rewind(inputfile); while(1) { temp = fgetc(inputfile); if(temp==EOF) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Reached end of file unexpectedly (5)."); messagewindow.exec(); fclose(inputfile); enable_widgets(TRUE); return; } if(temp==separator) { break; } } i = 0; while(temp!='\n') { temp = fgetc(inputfile); if(temp==EOF) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Reached end of file unexpectedly (6)."); messagewindow.exec(); fclose(inputfile); enable_widgets(TRUE); return; } if(temp=='\r') { continue; } if(((temp==separator)||(temp=='\n'))&&(edfsignals<7)) { if(edfsignals>=MAX_SIGNALS) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Too many labels/signals (7)."); messagewindow.exec(); fclose(inputfile); enable_widgets(TRUE); return; } line[i] = 0; ok = 0; if(!strcmp(line, "IBI")) { strcpy(labels[edfsignals], "IBI "); strcpy(phys_dim[edfsignals], "s "); strcpy(phys_min[edfsignals], "-31.744 "); strcpy(phys_max[edfsignals], "31.744 "); sensitivity[edfsignals] = 1000.0; ok = 1; } if(!strcmp(line, "HR")) { strcpy(labels[edfsignals], "HR "); strcpy(phys_dim[edfsignals], "bpm "); strcpy(phys_min[edfsignals], "-1024 "); strcpy(phys_max[edfsignals], "1024 "); sensitivity[edfsignals] = 31.0; ok = 1; } if(!strcmp(line, "LVET")) { strcpy(labels[edfsignals], "LVET "); strcpy(phys_dim[edfsignals], "s "); strcpy(phys_min[edfsignals], "-10 "); strcpy(phys_max[edfsignals], "10 "); sensitivity[edfsignals] = 3174.4; ok = 1; } if(!strcmp(line, "HRS")) { strcpy(labels[edfsignals], "HRS "); strcpy(phys_dim[edfsignals], "mmHg "); strcpy(phys_min[edfsignals], "-1024 "); strcpy(phys_max[edfsignals], "1024 "); sensitivity[edfsignals] = 31.0; ok = 1; } if(!strcmp(line, "Sys")) { strcpy(labels[edfsignals], "Sys "); strcpy(phys_dim[edfsignals], "mmHg "); strcpy(phys_min[edfsignals], "-1024 "); strcpy(phys_max[edfsignals], "1024 "); sensitivity[edfsignals] = 31.0; ok = 1; } if(!strcmp(line, "Dia")) { strcpy(labels[edfsignals], "Dia "); strcpy(phys_dim[edfsignals], "mmHg "); strcpy(phys_min[edfsignals], "-1024 "); strcpy(phys_max[edfsignals], "1024 "); sensitivity[edfsignals] = 31.0; ok = 1; } if(!strcmp(line, "MAP")) { strcpy(labels[edfsignals], "MAP "); strcpy(phys_dim[edfsignals], "mmHg "); strcpy(phys_min[edfsignals], "-1024 "); strcpy(phys_max[edfsignals], "1024 "); sensitivity[edfsignals] = 31.0; ok = 1; } if(!ok) { snprintf(txt_string, 2048, "Found unknown label/signal: %s", line); QMessageBox messagewindow(QMessageBox::Critical, "Error", txt_string); messagewindow.exec(); fclose(inputfile); enable_widgets(TRUE); return; } edfsignals++; i = 0; } if(temp==separator) { continue; } line[i++] = temp; } if(!edfsignals) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There are no labels/signals."); messagewindow.exec(); fclose(inputfile); enable_widgets(TRUE); return; } } /********** end if(file_type==100) ********************/ if(file_type==103) { edfsignals = 1; } if(file_type==32) { if(analoginputscombobox->currentIndex()==1) { edfsignals = 4; } else { edfsignals = 1; } } p = sprintf(patientname, "%s", PatientnameLineEdit->text().toLatin1().data()); latin1_to_ascii(patientname, p); for( ; p<80; p++) { patientname[p] = ' '; } patientname[80] = 0; p = sprintf(recording, "%s", RecordingLineEdit->text().toLatin1().data()); latin1_to_ascii(recording, p); for( ; p<80; p++) { recording[p] = ' '; } recording[80] = 0; sprintf(datetime, "%02i.%02i.%02i%02i.%02i.%02i", StartDatetimeedit->date().day(), StartDatetimeedit->date().month(), StartDatetimeedit->date().year() % 100, StartDatetimeedit->time().hour(), StartDatetimeedit->time().minute(), StartDatetimeedit->time().second()); datetime[16] = 0; /***************** write header *****************************************/ get_filename_from_path(outputfilename, path, MAX_PATH_LENGTH); remove_extension_from_filename(outputfilename); strcat(outputfilename, ".edf"); path[0] = 0; if(recent_savedir[0]!=0) { strcpy(path, recent_savedir); strcat(path, "/"); } strcat(path, outputfilename); 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); outputfile = fopeno(path, "wb"); if(outputfile==NULL) { snprintf(txt_string, 2048, "Can not open file %s for writing.", path); QMessageBox messagewindow(QMessageBox::Critical, "Error", txt_string); messagewindow.exec(); enable_widgets(TRUE); fclose(inputfile); return; } fprintf(outputfile, "0 "); fprintf(outputfile, "%s", patientname); fprintf(outputfile, "%s", recording); fprintf(outputfile, "%s", datetime); fprintf(outputfile, "%-8i", 256 * edfsignals + 256); fprintf(outputfile, " "); fprintf(outputfile, "-1 "); if(file_type==100) { fprintf(outputfile, "0.01 "); } if(file_type==103) { fprintf(outputfile, "0.005 "); } if(file_type==32) { fprintf(outputfile, "0.005 "); } fprintf(outputfile, "%-4i", edfsignals); if(file_type==100) { for(i=0; i0) break; } QApplication::setOverrideCursor(Qt::WaitCursor); for(k=0; k<10; k++) qApp->processEvents(); i = 0; column = 0; datarecords = 0LL; str_start = 0; line_nr = 1; while(1) { temp = fgetc(inputfile); if(temp==EOF) { for(k=0; k31744) temp = 31744; if(temp<-31744) temp = -31744; var.two = (short)temp; fputc(var.one[0], outputfile); fputc(var.one[1], outputfile); } datarecords++; break; } line[i] = temp; /**************************************/ if(line[i]==',') { line[i] = '.'; } if((line[i]==separator)||(line[i]=='\n')) { if(column) { new_value[column-1] = atof(line + str_start); } else { new_smpl_time = (int)(atof(line + str_start) * 100.0); } if(line[i]=='\n') { /**************************************/ line_nr++; if(column!=edfsignals) { QApplication::restoreOverrideCursor(); snprintf(txt_string, 2048, "Number of separators in line %i is wrong.", line_nr); QMessageBox messagewindow(QMessageBox::Critical, "Error", txt_string); messagewindow.exec(); fclose(inputfile); fclose(outputfile); enable_widgets(TRUE); return; } timestep = new_smpl_time - datarecords; if(timestep<=0) { QApplication::restoreOverrideCursor(); snprintf(txt_string, 2048, "Timestep <= 0 in line %i.", line_nr); QMessageBox messagewindow(QMessageBox::Critical, "Error", txt_string); messagewindow.exec(); fclose(inputfile); fclose(outputfile); enable_widgets(TRUE); return; } for(j=0; j31744) temp = 31744; if(temp<-31744) temp = -31744; var.two = (short)temp; fputc(var.one[0], outputfile); fputc(var.one[1], outputfile); } datarecords++; } for(j=0; j2046) { QApplication::restoreOverrideCursor(); snprintf(txt_string, 2048, "Line %i is too long.", line_nr); QMessageBox messagewindow(QMessageBox::Critical, "Error", txt_string); messagewindow.exec(); fclose(inputfile); fclose(outputfile); enable_widgets(TRUE); return; } } } /********** end if(file_type==100) ********************/ if((file_type==103) || (file_type==32)) { fseeko(inputfile, 0LL, SEEK_END); file_size = ftello(inputfile); file_size /= 2LL; file_size /= edfsignals; rewind(inputfile); QApplication::setOverrideCursor(Qt::WaitCursor); for(k=0; k<10; k++) qApp->processEvents(); if(file_type==103) { for(datarecords=0LL; datarecordssetEnabled(toggle); PatientnameLineEdit->setEnabled(toggle); RecordingLineEdit->setEnabled(toggle); pushButton1->setEnabled(toggle); pushButton2->setEnabled(toggle); } void UI_NEXFIN2EDFwindow::radiobuttonchecked(bool checked) { if(checked==TRUE) { analoginputscombobox->setEnabled(TRUE); } else { analoginputscombobox->setEnabled(FALSE); } } edfbrowser_153_source/PaxHeaders.2978/show_actual_montage_dialog.cpp0000644000175000001440000000013212251654530024215 xustar000000000000000030 mtime=1386699096.479032511 30 atime=1386699096.479032511 30 ctime=1386699096.479032511 edfbrowser_153_source/show_actual_montage_dialog.cpp0000644000175000001440000002314512251654530023753 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "show_actual_montage_dialog.h" UI_ShowActualMontagewindow::UI_ShowActualMontagewindow(QWidget *w_parent) { int i, j, type, model, order; char txtbuf[2048]; double frequency, frequency2, ripple; QStandardItem *parentItem, *signalItem, *filterItem; mainwindow = (UI_Mainwindow *)w_parent; ShowMontageDialog = new QDialog; ShowMontageDialog->setMinimumSize(QSize(500, 300)); ShowMontageDialog->resize(500, 440); ShowMontageDialog->setWindowTitle("Show montage"); ShowMontageDialog->setModal(TRUE); ShowMontageDialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); tree = new QTreeView; tree->setHeaderHidden(TRUE); tree->setIndentation(30); tree->setSelectionMode(QAbstractItemView::NoSelection); tree->setEditTriggers(QAbstractItemView::NoEditTriggers); tree->setSortingEnabled(FALSE); tree->setDragDropMode(QAbstractItemView::NoDragDrop); CloseButton = new QPushButton; CloseButton->setFixedSize(100, 25); CloseButton->setText("Close"); box = new QBoxLayout(QBoxLayout::TopToBottom, ShowMontageDialog); box->addWidget(tree); box->addWidget(CloseButton, 0, Qt::AlignRight); QObject::connect(CloseButton, SIGNAL(clicked()), ShowMontageDialog, SLOT(close())); t_model = new QStandardItemModel(this); parentItem = t_model->invisibleRootItem(); for(i=0; isignalcomps; i++) { txtbuf[0] = 0; if(mainwindow->signalcomp[i]->alias[0] != 0) { strcpy(txtbuf, "alias: "); strcat(txtbuf, mainwindow->signalcomp[i]->alias); strcat(txtbuf, " "); } for(j=0; jsignalcomp[i]->num_of_signals; j++) { sprintf(txtbuf + strlen(txtbuf), "%+ix %s", mainwindow->signalcomp[i]->factor[j], mainwindow->signalcomp[i]->edfhdr->edfparam[mainwindow->signalcomp[i]->edfsignal[j]].label); remove_trailing_spaces(txtbuf); strcat(txtbuf, " "); } if(mainwindow->signalcomp[i]->polarity == -1) { strcat(txtbuf, "Inverted: yes"); } signalItem = new QStandardItem(txtbuf); parentItem->appendRow(signalItem); sprintf(txtbuf, "amplitude: %f", mainwindow->signalcomp[i]->voltpercm); strcat(txtbuf, mainwindow->signalcomp[i]->physdimension); remove_trailing_spaces(txtbuf); sprintf(txtbuf + strlen(txtbuf), "/cm offset: %f%s", mainwindow->signalcomp[i]->screen_offset * mainwindow->pixelsizefactor * mainwindow->signalcomp[i]->voltpercm, mainwindow->signalcomp[i]->physdimension); remove_trailing_zeros(txtbuf); remove_trailing_spaces(txtbuf); strcat(txtbuf, " color: "); switch(mainwindow->signalcomp[i]->color) { case Qt::white : strcat(txtbuf, "white"); break; case Qt::black : strcat(txtbuf, "black"); break; case Qt::red : strcat(txtbuf, "red"); break; case Qt::darkRed : strcat(txtbuf, "dark red"); break; case Qt::green : strcat(txtbuf, "green"); break; case Qt::darkGreen : strcat(txtbuf, "dark green"); break; case Qt::blue : strcat(txtbuf, "blue"); break; case Qt::darkBlue : strcat(txtbuf, "dark blue"); break; case Qt::cyan : strcat(txtbuf, "cyan"); break; case Qt::darkCyan : strcat(txtbuf, "dark cyan"); break; case Qt::magenta : strcat(txtbuf, "magenta"); break; case Qt::darkMagenta : strcat(txtbuf, "dark magenta"); break; case Qt::yellow : strcat(txtbuf, "yellow"); break; case Qt::darkYellow : strcat(txtbuf, "dark yellow"); break; case Qt::gray : strcat(txtbuf, "gray"); break; case Qt::darkGray : strcat(txtbuf, "dark gray"); break; case Qt::lightGray : strcat(txtbuf, "light gray"); break; } signalItem->appendRow(new QStandardItem(txtbuf)); filterItem = new QStandardItem("Filters"); signalItem->appendRow(filterItem); for(j=0; jsignalcomp[i]->filter_cnt; j++) { if(mainwindow->signalcomp[i]->filter[j]->is_LPF == 1) { sprintf(txtbuf, "LPF: %fHz", mainwindow->signalcomp[i]->filter[j]->cutoff_frequency); } if(mainwindow->signalcomp[i]->filter[j]->is_LPF == 0) { sprintf(txtbuf, "HPF: %fHz", mainwindow->signalcomp[i]->filter[j]->cutoff_frequency); } remove_trailing_zeros(txtbuf); filterItem->appendRow(new QStandardItem(txtbuf)); } for(j=0; jsignalcomp[i]->ravg_filter_cnt; j++) { if(mainwindow->signalcomp[i]->ravg_filter_type[j] == 0) { sprintf(txtbuf, "highpass moving average %i smpls", mainwindow->signalcomp[i]->ravg_filter[j]->size); } if(mainwindow->signalcomp[i]->ravg_filter_type[j] == 1) { sprintf(txtbuf, "lowpass moving average %i smpls", mainwindow->signalcomp[i]->ravg_filter[j]->size); } filterItem->appendRow(new QStandardItem(txtbuf)); } for(j=0; jsignalcomp[i]->fidfilter_cnt; j++) { type = mainwindow->signalcomp[i]->fidfilter_type[j]; model = mainwindow->signalcomp[i]->fidfilter_model[j]; frequency = mainwindow->signalcomp[i]->fidfilter_freq[j]; frequency2 = mainwindow->signalcomp[i]->fidfilter_freq2[j]; order = mainwindow->signalcomp[i]->fidfilter_order[j]; ripple = mainwindow->signalcomp[i]->fidfilter_ripple[j]; if(type == 0) { if(model == 0) { sprintf(txtbuf, "highpass Butterworth %fHz %ith order", frequency, order); } if(model == 1) { sprintf(txtbuf, "highpass Chebyshev %fHz %ith order %fdB ripple", frequency, order, ripple); } if(model == 2) { sprintf(txtbuf, "highpass Bessel %fHz %ith order", frequency, order); } } if(type == 1) { if(model == 0) { sprintf(txtbuf, "lowpass Butterworth %fHz %ith order", frequency, order); } if(model == 1) { sprintf(txtbuf, "lowpass Chebyshev %fHz %ith order %fdB ripple", frequency, order, ripple); } if(model == 2) { sprintf(txtbuf, "lowpass Bessel %fHz %ith order", frequency, order); } } if(type == 2) { sprintf(txtbuf, "notch %fHz Q-factor %i", frequency, order); } if(type == 3) { if(model == 0) { sprintf(txtbuf, "bandpass Butterworth %f-%fHz %ith order", frequency, frequency2, order); } if(model == 1) { sprintf(txtbuf, "bandpass Chebyshev %f-%fHz %ith order %fdB ripple", frequency, frequency2, order, ripple); } if(model == 2) { sprintf(txtbuf, "bandpass Bessel %f-%fHz %ith order", frequency, frequency2, order); } } if(type == 4) { if(model == 0) { sprintf(txtbuf, "bandstop Butterworth %f-%fHz %ith order", frequency, frequency2, order); } if(model == 1) { sprintf(txtbuf, "bandstop Chebyshev %f-%fHz %ith order %fdB ripple", frequency, frequency2, order, ripple); } if(model == 2) { sprintf(txtbuf, "bandstop Bessel %f-%fHz %ith order", frequency, frequency2, order); } } remove_trailing_zeros(txtbuf); filterItem->appendRow(new QStandardItem(txtbuf)); } if(mainwindow->signalcomp[i]->ecg_filter != NULL) { sprintf(txtbuf, "ECG heartrate detection"); filterItem->appendRow(new QStandardItem(txtbuf)); } if(mainwindow->signalcomp[i]->zratio_filter != NULL) { sprintf(txtbuf, "Z-ratio cross-over frequency is %.1f Hz", mainwindow->signalcomp[i]->zratio_crossoverfreq); filterItem->appendRow(new QStandardItem(txtbuf)); } } sprintf(txtbuf, "timescale: %f seconds", (double)mainwindow->pagetime / (double)TIME_DIMENSION); remove_trailing_zeros(txtbuf); parentItem->appendRow(new QStandardItem(txtbuf)); tree->setModel(t_model); ShowMontageDialog->exec(); } edfbrowser_153_source/PaxHeaders.2978/filteredblockread.h0000644000175000001440000000013212251654530021765 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/filteredblockread.h0000644000175000001440000000354512251654530021525 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef filteredblockread_INCLUDED #define filteredblockread_INCLUDED #include #include #include #include "global.h" #include "filter.h" #include "ravg_filter.h" #include "third_party/fidlib/fidlib.h" class FilteredBlockReadClass { private: FILE *inputfile; struct edfhdrblock *hdr; struct signalcompblock *signalcomp; int datarecord_cnt, samples_per_datrec, total_samples, skip_filters; char *readbuf; double *processed_samples_buf, bitvalue; public: double * init_signalcomp(struct signalcompblock *, int, int); int process_signalcomp(int); int samples_in_buf(void); FilteredBlockReadClass(); ~FilteredBlockReadClass(); }; #endif edfbrowser_153_source/PaxHeaders.2978/utils.h0000644000175000001440000000013212251654530017460 xustar000000000000000030 mtime=1386699096.468032569 30 atime=1386699096.468032569 30 ctime=1386699096.468032569 edfbrowser_153_source/utils.h0000644000175000001440000000570412251654530017217 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef UTILS_INCLUDED #define UTILS_INCLUDED #ifdef __cplusplus extern "C" { #endif #include #include #include #include void remove_trailing_spaces(char *); void remove_leading_spaces(char *); void remove_trailing_zeros(char *); void convert_trailing_zeros_to_spaces(char *); void remove_extension_from_filename(char *); /* removes extension including the dot */ int get_filename_from_path(char *dest, const char *src, int size); /* size is size of destination, returns length of filename */ int get_directory_from_path(char *dest, const char *src, int size); /* size is size of destination, returns length of directory */ void latin1_to_ascii(char *, int); void latin1_to_utf8(char *, int); void utf8_to_latin1(char *); int antoi(const char *, int); int atoi_nonlocalized(const char *); double atof_nonlocalized(const char *); int sprint_number_nonlocalized(char *, double); long long atoll_x(const char *, int); void strntolower(char *, int); /* 3th argument is the minimum digits that will be printed (minus sign not included), leading zero's will be added if necessary */ /* if 4th argument is zero, only negative numbers will have the sign '-' character */ /* if 4th argument is one, the sign '+' or '-' character will always be printed */ /* returns the amount of characters printed */ int sprint_int_number_nonlocalized(char *, int, int, int); int sprint_ll_number_nonlocalized(char *, long long, int, int); int fprint_int_number_nonlocalized(FILE *, int, int, int); int fprint_ll_number_nonlocalized(FILE *, long long, int, int); /* returns 1 in case the string is not a number */ int is_integer_number(char *); int is_number(char *); int round_125_cat(double); /* returns 10, 20 or 50, depending on the value */ #ifdef __cplusplus } /* extern "C" */ #endif #endif edfbrowser_153_source/PaxHeaders.2978/ecg_filter.cpp0000644000175000001440000000013212251654530020756 xustar000000000000000030 mtime=1386699096.477032522 30 atime=1386699096.477032522 30 ctime=1386699096.477032522 edfbrowser_153_source/ecg_filter.cpp0000644000175000001440000005116012251654530020512 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * The current version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "ecg_filter.h" #define ECG_FILTER_STAT_BUFSIZE 262144 #define SECONDS_RUNIN 5 // #define ECG_FILTER_DEBUG_ACTIVE struct ecg_filter_settings * create_ecg_filter(double sf, double bitval, int powerlinefreq) { int i; double d_tmp; struct ecg_filter_settings *settings; if(sf < 99.9) return(NULL); if((powerlinefreq != 50) && (powerlinefreq != 60)) return(NULL); settings = (struct ecg_filter_settings *) calloc(1, sizeof(struct ecg_filter_settings)); if(settings==NULL) return(NULL); d_tmp = sf / (double)powerlinefreq; settings->avgfilter_50_size = d_tmp; if((d_tmp - settings->avgfilter_50_size) > 0.5) settings->avgfilter_50_size++; d_tmp = sf / 35.0; settings->avgfilter_35_size = d_tmp; if((d_tmp - settings->avgfilter_35_size) > 0.5) settings->avgfilter_35_size++; d_tmp = sf / 25.0; settings->avgfilter_25_size = d_tmp; if((d_tmp - settings->avgfilter_25_size) > 0.5) settings->avgfilter_25_size++; settings->avgfilter_50_idx = 0; settings->avgfilter_35_idx = 0; settings->avgfilter_25_idx = 0; settings->avgfilter_50_buf = (double *)calloc(1, settings->avgfilter_50_size * sizeof(double)); if(settings->avgfilter_50_buf == NULL) { free(settings); return(NULL); } settings->avgfilter_50_buf_bu = (double *)calloc(1, settings->avgfilter_50_size * sizeof(double)); if(settings->avgfilter_50_buf_bu == NULL) { free(settings->avgfilter_50_buf); free(settings); return(NULL); } settings->avgfilter_35_buf = (double *)calloc(1, settings->avgfilter_35_size * sizeof(double)); if(settings->avgfilter_35_buf == NULL) { free(settings->avgfilter_50_buf); free(settings->avgfilter_50_buf_bu); free(settings); return(NULL); } settings->avgfilter_35_buf_bu = (double *)calloc(1, settings->avgfilter_35_size * sizeof(double)); if(settings->avgfilter_35_buf_bu == NULL) { free(settings->avgfilter_50_buf); free(settings->avgfilter_50_buf_bu); free(settings->avgfilter_35_buf); free(settings); return(NULL); } settings->avgfilter_25_buf = (double *)calloc(1, settings->avgfilter_25_size * sizeof(double)); if(settings->avgfilter_25_buf == NULL) { free(settings->avgfilter_50_buf); free(settings->avgfilter_50_buf_bu); free(settings->avgfilter_35_buf); free(settings->avgfilter_35_buf_bu); free(settings); return(NULL); } settings->avgfilter_25_buf_bu = (double *)calloc(1, settings->avgfilter_25_size * sizeof(double)); if(settings->avgfilter_25_buf_bu == NULL) { free(settings->avgfilter_50_buf); free(settings->avgfilter_50_buf_bu); free(settings->avgfilter_35_buf); free(settings->avgfilter_35_buf_bu); free(settings->avgfilter_25_buf); free(settings); return(NULL); } settings->SV_idx = 0; settings->SV_sz = ((((int)sf) + 25) / 100) + 1; if(settings->SV_sz < 3) { settings->SV_sz = 3; } settings->SV = (double *)calloc(1, settings->SV_sz * sizeof(double)); if(settings->SV == NULL) { free(settings->avgfilter_50_buf); free(settings->avgfilter_50_buf_bu); free(settings->avgfilter_35_buf); free(settings->avgfilter_35_buf_bu); free(settings->avgfilter_25_buf); free(settings->avgfilter_25_buf_bu); free(settings); return(NULL); } settings->M_startslope = sf * 0.2; settings->M_endslope = sf * 1.2; settings->smpl_n = 0; for(i=0; i<5; i++) { settings->M[i] = 0.0; } settings->M_avg = 0.0; settings->M_idx = 0; settings->drain = 0.0; settings->top = 0.0; settings->runin = SECONDS_RUNIN * sf; settings->sf = sf; settings->F_size = 0.35 * sf; settings->F_wd = 0.05 * sf; settings->F_sf_factor = 150.0 * (sf / 200.0); if(settings->F_sf_factor < 150.0) { settings->F_sf_factor = 150.0; } settings->F_value = 0.0; settings->F_idx = 0; settings->F = (double *)calloc(1, settings->F_size * sizeof(double)); if(settings->F == NULL) { free(settings->avgfilter_50_buf); free(settings->avgfilter_50_buf_bu); free(settings->avgfilter_35_buf); free(settings->avgfilter_35_buf_bu); free(settings->avgfilter_25_buf); free(settings->SV); free(settings); return(NULL); } settings->F_bu = (double *)calloc(1, settings->F_size * sizeof(double)); if(settings->F_bu == NULL) { free(settings->avgfilter_50_buf); free(settings->avgfilter_50_buf_bu); free(settings->avgfilter_35_buf); free(settings->avgfilter_35_buf_bu); free(settings->avgfilter_25_buf); free(settings->SV); free(settings->F); free(settings); return(NULL); } for(i=0; i<5; i++) { settings->R[i] = sf; } settings->R_idx = 0; settings->R_avg = sf; settings->R_value = 0.0; settings->R_startslope = sf * 0.66; settings->R_endslope = sf; settings->bu_filled = 0; settings->bpm = 60.0; settings->bitvalue = bitval; settings->stat_buf_idx = 0; settings->sample_cntr = 0; settings->T_peak_avg = 0.0; settings->stat_buf = (double *)malloc(sizeof(double) * ECG_FILTER_STAT_BUFSIZE); if(settings->stat_buf == NULL) { free(settings->avgfilter_50_buf); free(settings->avgfilter_50_buf_bu); free(settings->avgfilter_35_buf); free(settings->avgfilter_35_buf_bu); free(settings->avgfilter_25_buf); free(settings->SV); free(settings->F); free(settings->F_bu); free(settings); return(NULL); } settings->stat_smpl_buf = (long long *)malloc(sizeof(long long) * ECG_FILTER_STAT_BUFSIZE); if(settings->stat_smpl_buf == NULL) { free(settings->avgfilter_50_buf); free(settings->avgfilter_50_buf_bu); free(settings->avgfilter_35_buf); free(settings->avgfilter_35_buf_bu); free(settings->avgfilter_25_buf); free(settings->SV); free(settings->F); free(settings->F_bu); free(settings->stat_buf); free(settings); return(NULL); } return(settings); } double run_ecg_filter(double new_sample, struct ecg_filter_settings *settings) // double run_ecg_filter(double new_sample, struct ecg_filter_settings *settings, int signalcompnr) // debug { int i, j; double new_input, max_value, result; /* running average filter 1 */ settings->avgfilter_50_buf[settings->avgfilter_50_idx] = new_sample; settings->avgfilter_50_idx++; if(settings->avgfilter_50_idx >= settings->avgfilter_50_size) { settings->avgfilter_50_idx = 0; } settings->avgfilter_50_mean = 0.0; for(i=0; iavgfilter_50_size; i++) { settings->avgfilter_50_mean += settings->avgfilter_50_buf[i]; } settings->avgfilter_50_mean /= settings->avgfilter_50_size; /* running average filter 2 */ settings->avgfilter_35_buf[settings->avgfilter_35_idx] = settings->avgfilter_50_mean; settings->avgfilter_35_idx++; if(settings->avgfilter_35_idx >= settings->avgfilter_35_size) { settings->avgfilter_35_idx = 0; } settings->avgfilter_35_mean = 0.0; for(i=0; iavgfilter_35_size; i++) { settings->avgfilter_35_mean += settings->avgfilter_35_buf[i]; } settings->avgfilter_35_mean /= settings->avgfilter_35_size; /* running average filter 3 */ settings->avgfilter_25_buf[settings->avgfilter_25_idx] = settings->avgfilter_35_mean; settings->avgfilter_25_idx++; if(settings->avgfilter_25_idx >= settings->avgfilter_25_size) { settings->avgfilter_25_idx = 0; } settings->avgfilter_25_mean = 0.0; for(i=0; iavgfilter_25_size; i++) { settings->avgfilter_25_mean += settings->avgfilter_25_buf[i]; } settings->avgfilter_25_mean /= settings->avgfilter_25_size; // return(settings->avgfilter_25_mean); // debug // if(signalcompnr == 1) return(settings->avgfilter_25_mean); // debug /* spatial velocity filter */ settings->SV[settings->SV_idx] = settings->avgfilter_25_mean; new_input = settings->SV[settings->SV_idx] - settings->SV[(settings->SV_idx + 1) % settings->SV_sz]; if(++settings->SV_idx >= settings->SV_sz) settings->SV_idx = 0; if(new_input < 0.0) new_input *= -1.0; // return(new_input); // debug // if(signalcompnr == 2) return(new_input); // debug settings->F[settings->F_idx++] = new_input; settings->F_idx %= settings->F_size; max_value = 0.0; for(i=0; iF_wd; i++) { j = (settings->F_idx + settings->F_size - i - 1) % settings->F_size; if(settings->F[j] > max_value) { max_value = settings->F[j]; } } result = max_value; max_value = 0.0; for(i=0; iF_wd; i++) { j = (settings->F_idx + i) % settings->F_size; if(settings->F[j] > max_value) { max_value = settings->F[j]; } } result -= max_value; settings->F_value += (result / settings->F_sf_factor); // return(settings->F_value); // debug //////////////////////////////////////////////// if(settings->runin) { if(settings->sample_cntr > settings->sf) { if(new_input > settings->top) { settings->top = new_input; } if(new_input > settings->T_peak_avg) { settings->T_peak_avg = new_input; } } if(settings->sample_cntr == settings->sf) { settings->F_value = 0.0; settings->F_idx = 0; memset(settings->F, 0, settings->F_size * sizeof(double)); } if(settings->runin == 1) { for(i=0; i<5; i++) { settings->M[i] = settings->top * 0.5; } settings->M_avg = settings->top * 0.5; settings->drain = settings->top * 0.2 / settings->sf; settings->smpl_n = settings->M_startslope; #ifdef ECG_FILTER_DEBUG_ACTIVE printf("-> settings->drain is %f\n", settings->drain); printf("-> settings->M_avg is %f\n", settings->M_avg); #endif } settings->runin--; settings->sample_cntr++; // if(signalcompnr == 6) return(settings->M_avg + settings->R_value); // debug: check ecg detection treshold // if(signalcompnr == 3) return(settings->M_avg); // debug: check ecg detection treshold // if(signalcompnr == 4) return(settings->F_value); // debug: check ecg detection treshold // if(signalcompnr == 5) return(settings->R_value); // debug: check ecg detection treshold // if(signalcompnr == 7) return(settings->T_peak_avg / 2.0); // debug: check ecg detection treshold return(settings->bpm / settings->bitvalue); } if(new_input > settings->T_peak_avg) { settings->T_peak_avg += ((new_input - settings->T_peak_avg) / (settings->sf / 10.0)); } else { settings->T_peak_avg -= (settings->T_peak_avg / (settings->sf * 10.0)); } if((settings->smpl_n > settings->R_startslope) && (settings->smpl_n < settings->R_endslope)) { settings->R_value -= (settings->drain * 0.7); } if(settings->smpl_n < settings->M_startslope) { if(new_input > settings->top) { settings->top = new_input; #ifdef ECG_FILTER_DEBUG_ACTIVE printf("new_input is %f\n", new_input); #endif } settings->sample_cntr++; settings->smpl_n++; } else { if(settings->smpl_n == settings->M_startslope) { settings->top *= 0.6; #ifdef ECG_FILTER_DEBUG_ACTIVE printf("settings->top is %f\n", settings->top); #endif if(settings->top > (1.5 * settings->M[settings->M_idx])) { settings->top = 1.1 * settings->M[settings->M_idx]; } settings->M[settings->M_idx++] = settings->top; settings->M_idx %= 5; settings->M_avg = (settings->M[0] + settings->M[1] + settings->M[2] + settings->M[3] + settings->M[4]) / 5.0; settings->drain = settings->M_avg * 0.4 / settings->sf; #ifdef ECG_FILTER_DEBUG_ACTIVE printf("settings->top is %f\n", settings->top); printf("settings->M_avg is %f\n", settings->M_avg); printf("settings->drain is %f\n", settings->drain); #endif } if((new_input > (settings->M_avg + settings->F_value + settings->R_value)) // beat detected? && (new_input > (settings->T_peak_avg / 2.0))) // if(new_input > (settings->M_avg + settings->F_value + settings->R_value)) // beat detected? // if(new_input > (settings->M_avg + settings->R_value)) // beat detected? // debug // if(new_input > (settings->M_avg)) // debug { settings->top = new_input; settings->R[settings->R_idx++] = settings->smpl_n; #ifdef ECG_FILTER_DEBUG_ACTIVE printf("beat detected: settings->top is %f\n", settings->top); printf("beat detected: settings->smpl_n is %i\n", settings->smpl_n); #endif settings->R_idx %= 5; settings->R_avg = (settings->R[0] + settings->R[1] + settings->R[2] + settings->R[3] + settings->R[4]) / 5; settings->R_value = 0.0; settings->R_startslope = 0.66 * settings->R_avg; settings->R_endslope = settings->R_avg; settings->bpm = (settings->sf * 60.0) / settings->smpl_n; if(settings->stat_buf_idx < (ECG_FILTER_STAT_BUFSIZE - 1)) { settings->stat_buf[settings->stat_buf_idx] = ((double)settings->smpl_n) / settings->sf; if(settings->stat_buf_idx > 0) { settings->stat_smpl_buf[settings->stat_buf_idx] = settings->stat_smpl_buf[settings->stat_buf_idx - 1] + settings->sample_cntr; } else { settings->stat_smpl_buf[settings->stat_buf_idx] = settings->sample_cntr; } settings->stat_buf_idx++; } settings->sample_cntr = 1; settings->smpl_n = 1; } else { if(settings->smpl_n < settings->M_endslope) { settings->M_avg -= settings->drain; } settings->sample_cntr++; settings->smpl_n++; } } // if(signalcompnr == 6) return(settings->M_avg + settings->F_value + settings->R_value); // debug: check ecg detection treshold // if(signalcompnr == 6) return(settings->M_avg + settings->R_value); // debug: check ecg detection treshold // if(signalcompnr == 3) return(settings->M_avg); // debug: check ecg detection treshold // if(signalcompnr == 4) return(settings->F_value); // debug: check ecg detection treshold // if(signalcompnr == 5) return(settings->R_value); // debug: check ecg detection treshold // if(signalcompnr == 7) return(settings->T_peak_avg / 2.0); // debug: check ecg detection treshold return(settings->bpm / settings->bitvalue); } void ecg_filter_save_buf(struct ecg_filter_settings *settings) { int i; settings->avgfilter_50_idx_bu = settings->avgfilter_50_idx; memcpy(settings->avgfilter_50_buf_bu, settings->avgfilter_50_buf, sizeof(double) * settings->avgfilter_50_size); settings->avgfilter_50_mean_bu = settings->avgfilter_50_mean; settings->avgfilter_35_idx_bu = settings->avgfilter_35_idx; memcpy(settings->avgfilter_35_buf_bu, settings->avgfilter_35_buf, sizeof(double) * settings->avgfilter_35_size); settings->avgfilter_35_mean_bu = settings->avgfilter_35_mean; settings->avgfilter_25_idx_bu = settings->avgfilter_25_idx; memcpy(settings->avgfilter_25_buf_bu, settings->avgfilter_25_buf, sizeof(double) * settings->avgfilter_25_size); settings->avgfilter_25_mean_bu = settings->avgfilter_25_mean; settings->runin_bu = settings->runin; for(i=0; i<3; i++) { settings->SV_bu[i] = settings->SV[i]; } settings->SV_idx_bu = settings->SV_idx; settings->smpl_n_bu = settings->smpl_n; for(i=0; i<5; i++) { settings->M_bu[i] = settings->M[i]; settings->R_bu[i] = settings->R[i]; } settings->M_idx_bu = settings->M_idx; settings->M_avg_bu = settings->M_avg; settings->drain_bu = settings->drain; settings->top_bu = settings->top; for(i=0; iF_size; i++) { settings->F_bu[i] = settings->F[i]; } settings->F_idx_bu = settings->F_idx; settings->F_value_bu = settings->F_value; settings->R_idx_bu = settings->R_idx; settings->R_avg_bu = settings->R_avg; settings->R_value_bu = settings->R_value; settings->R_startslope_bu = settings->R_startslope; settings->R_endslope_bu = settings->R_endslope; settings->bpm_bu = settings->bpm; settings->T_peak_avg_bu = settings->T_peak_avg; settings->bu_filled = 1; } void ecg_filter_restore_buf(struct ecg_filter_settings *settings) { int i; settings->stat_buf_idx = 0; settings->sample_cntr = 0; if(settings->bu_filled == 0) return; settings->avgfilter_50_idx = settings->avgfilter_50_idx_bu; memcpy(settings->avgfilter_50_buf, settings->avgfilter_50_buf_bu, sizeof(double) * settings->avgfilter_50_size); settings->avgfilter_50_mean = settings->avgfilter_50_mean_bu; settings->avgfilter_35_idx = settings->avgfilter_35_idx_bu; memcpy(settings->avgfilter_35_buf, settings->avgfilter_35_buf_bu, sizeof(double) * settings->avgfilter_35_size); settings->avgfilter_35_mean = settings->avgfilter_35_mean_bu; settings->avgfilter_25_idx = settings->avgfilter_25_idx_bu; memcpy(settings->avgfilter_25_buf, settings->avgfilter_25_buf_bu, sizeof(double) * settings->avgfilter_25_size); settings->avgfilter_25_mean = settings->avgfilter_25_mean_bu; settings->runin = settings->runin_bu; for(i=0; i<3; i++) { settings->SV[i] = settings->SV_bu[i]; } settings->SV_idx = settings->SV_idx_bu; settings->smpl_n = settings->smpl_n_bu; for(i=0; i<5; i++) { settings->M[i] = settings->M_bu[i]; settings->R[i] = settings->R_bu[i]; } settings->M_idx = settings->M_idx_bu; settings->M_avg = settings->M_avg_bu; settings->drain = settings->drain_bu; settings->top = settings->top_bu; for(i=0; iF_size; i++) { settings->F[i] = settings->F_bu[i]; } settings->F_idx = settings->F_idx_bu; settings->F_value = settings->F_value_bu; settings->R_idx = settings->R_idx_bu; settings->R_avg = settings->R_avg_bu; settings->R_value = settings->R_value_bu; settings->R_startslope = settings->R_startslope_bu; settings->R_endslope = settings->R_endslope_bu; settings->bpm = settings->bpm_bu; settings->T_peak_avg = settings->T_peak_avg_bu; } void reset_ecg_filter(struct ecg_filter_settings *settings) { int i; settings->avgfilter_50_idx = 0; settings->avgfilter_35_idx = 0; settings->avgfilter_25_idx = 0; memset(settings->avgfilter_50_buf, 0, settings->avgfilter_50_size * sizeof(double)); memset(settings->avgfilter_35_buf, 0, settings->avgfilter_35_size * sizeof(double)); memset(settings->avgfilter_25_buf, 0, settings->avgfilter_25_size * sizeof(double)); settings->SV_idx = 0; for(i=0; iSV_sz; i++) { settings->SV[i] = 0.0; } settings->smpl_n = 0; for(i=0; i<5; i++) { settings->M[i] = 0.0; } settings->M_avg = 0.0; settings->M_idx = 0; settings->drain = 0.0; settings->top = 0.0; settings->runin = SECONDS_RUNIN * settings->sf; settings->F_value = 0.0; settings->F_idx = 0; memset(settings->F, 0, settings->F_size * sizeof(double)); for(i=0; i<5; i++) { settings->R[i] = settings->sf; } settings->R_idx = 0; settings->R_avg = settings->sf; settings->R_value = 0.0; settings->R_startslope = settings->sf * 0.66; settings->R_endslope = settings->sf; settings->bu_filled = 0; settings->bpm = 60.0; settings->stat_buf_idx = 0; settings->sample_cntr = 0; settings->T_peak_avg = 0.0; } void free_ecg_filter(struct ecg_filter_settings *settings) { free(settings->avgfilter_50_buf); free(settings->avgfilter_50_buf_bu); free(settings->avgfilter_35_buf); free(settings->avgfilter_35_buf_bu); free(settings->avgfilter_25_buf); free(settings->SV); free(settings->F); free(settings->F_bu); free(settings->stat_buf); free(settings->stat_smpl_buf); free(settings); } int ecg_filter_get_beat_cnt(struct ecg_filter_settings *settings) { return(settings->stat_buf_idx); } long long * ecg_filter_get_onset_beatlist(struct ecg_filter_settings *settings) { return(settings->stat_smpl_buf); } double * ecg_filter_get_interval_beatlist(struct ecg_filter_settings *settings) { return(settings->stat_buf); } edfbrowser_153_source/PaxHeaders.2978/mainwindow.cpp0000644000175000001440000000013212251654530021027 xustar000000000000000030 mtime=1386699096.478032517 30 atime=1386699096.478032517 30 ctime=1386699096.478032517 edfbrowser_153_source/mainwindow.cpp0000644000175000001440000052527412251654530020577 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "mainwindow.h" #if defined(__APPLE__) || defined(__MACH__) || defined(__APPLE_CC__) #define fopeno fopen #else #define fseeko fseeko64 #define ftello ftello64 #define fopeno fopen64 #endif UI_Mainwindow::UI_Mainwindow() { int i, j, k; live_stream_timer = new QTimer; live_stream_timer->setSingleShot(TRUE); QObject::connect(live_stream_timer, SIGNAL(timeout()), this, SLOT(live_stream_timer_func())); setMinimumSize(QSize(640, 480)); setWindowTitle(PROGRAM_NAME); setWindowIcon(QIcon(":/images/edf.png")); myfont = new QFont; monofont = new QFont; #ifdef Q_WS_X11 QApplication::setFont(*myfont); myfont->setFamily("Arial"); myfont->setPixelSize(12); monofont->setFamily("andale mono"); monofont->setPixelSize(12); #endif #ifdef Q_WS_MAC QApplication::setFont(*myfont); myfont->setFamily("Arial"); myfont->setPixelSize(12); monofont->setFamily("andale mono"); monofont->setPixelSize(12); #endif #ifdef Q_WS_WIN myfont->setFamily("Tahoma"); myfont->setPixelSize(11); monofont->setFamily("courier"); monofont->setPixelSize(12); #endif setlocale(LC_NUMERIC, "C"); pixelsizefactor = 0.0294382; x_pixelsizefactor = 0.0294382; viewtime_indicator_type = 1; mainwindow_title_type = 1; check_for_updates = 1; use_threads = 1; auto_dpi = 1; show_annot_markers = 1; show_baselines = 1; clip_to_pane = 0; auto_reload_mtg = 1; read_biosemi_status_signal = 1; read_nk_trigger_signal = 1; maxfilesize_to_readin_annotations = 10485760000LL; exit_in_progress = 0; live_stream_active = 0; signal_averaging_active = 0; live_stream_update_interval = 500; powerlinefreq = 50; mousewheelsens = 10; amplitude_doubler = 10; timescale_doubler = 10; recent_montagedir[0] = 0; recent_savedir[0] = 0; recent_opendir[0] = 0; recent_colordir[0] = 0; cfg_app_version[0] = 0; for(i=0; ifreq[i] = 1.0; spectrum_colorbar->color[i] = Qt::white; } spectrum_colorbar->items = 5; spectrum_colorbar->freq[0] = 4.0; spectrum_colorbar->freq[1] = 8.0; spectrum_colorbar->freq[2] = 12.0; spectrum_colorbar->freq[3] = 30.0; spectrum_colorbar->freq[4] = 100.0; spectrum_colorbar->color[0] = Qt::darkRed; spectrum_colorbar->color[1] = Qt::darkGreen; spectrum_colorbar->color[2] = Qt::darkBlue; spectrum_colorbar->color[3] = Qt::darkCyan; spectrum_colorbar->color[4] = Qt::darkMagenta; spectrum_colorbar->method = 1; maxdftblocksize = 1000; import_annotations_var = (import_annotations_var_block *)calloc(1, sizeof(struct import_annotations_var_block)); strcpy(import_annotations_var->separator, "tab"); import_annotations_var->format = 1; import_annotations_var->onsettimeformat = 0; import_annotations_var->onsetcolumn = 1; import_annotations_var->descriptioncolumn = 2; import_annotations_var->useduration = 0; import_annotations_var->durationcolumn = 3; import_annotations_var->datastartline = 1; import_annotations_var->dceventbittime = 10; import_annotations_var->triggerlevel = 500.0; import_annotations_var->manualdescription = 0; import_annotations_var->description[0] = 0; import_annotations_var->ignoreconsecutive = 0; export_annotations_var = (export_annotations_var_block *)calloc(1, sizeof(struct export_annotations_var_block)); export_annotations_var->separator = 0; export_annotations_var->format = 1; export_annotations_var->duration = 0; average_period = 0.3; average_ratio = 0; average_upsidedown = 0; average_bw = 0; spectrum_bw = 0; spectrum_sqrt = 0; z_score_var.crossoverfreq = 7.5; z_score_var.z_threshold = 0.0; z_score_var.zscore_page_len = 30; z_score_var.zscore_error_detection = 80; z_score_var.z_hysteresis = 0.0; raw2edf_var.sf = 256; raw2edf_var.chns = 1; raw2edf_var.phys_max = 3000; raw2edf_var.straightbinary = 0; raw2edf_var.endianness = 0; raw2edf_var.samplesize = 2; raw2edf_var.offset = 0; raw2edf_var.skipblocksize = 0; raw2edf_var.skipbytes = 1; strcpy(raw2edf_var.phys_dim, "uV"); read_general_settings(); maincurve = new ViewCurve(this); dpix = maincurve->logicalDpiX(); dpiy = maincurve->logicalDpiY(); if(auto_dpi) { pixelsizefactor = 1.0 / ((double)dpiy / 2.54); x_pixelsizefactor = 1.0 / ((double)dpix / 2.54); } read_color_settings(); setCentralWidget(maincurve); menubar = menuBar(); recent_filesmenu = new QMenu(this); recent_filesmenu->setTitle("Recent files"); connect(recent_filesmenu, SIGNAL(triggered(QAction *)), this, SLOT(recent_file_action_func(QAction *))); print_img_menu = new QMenu(this); print_img_menu->setTitle("to Image"); print_img_menu->addAction("640 x 480", this, SLOT(print_to_img_640x480())); print_img_menu->addAction("800 x 600", this, SLOT(print_to_img_800x600())); print_img_menu->addAction("1024 x 768", this, SLOT(print_to_img_1024x768())); print_img_menu->addAction("1280 x 1024", this, SLOT(print_to_img_1280x1024())); print_img_menu->addAction("1600 x 1200", this, SLOT(print_to_img_1600x1200())); printmenu = new QMenu(this); printmenu->setTitle("Print"); printmenu->addAction("to Printer", maincurve, SLOT(print_to_printer()), QKeySequence::Print); printmenu->addAction("to PostScript", maincurve, SLOT(print_to_postscript())); printmenu->addAction("to PDF", maincurve, SLOT(print_to_pdf())); printmenu->addMenu(print_img_menu); printmenu->addAction("to EDF", this, SLOT(print_to_edf())); printmenu->addAction("to BDF", this, SLOT(print_to_bdf())); #ifdef BK_MRS_project // temporary code for private use in a certain project // do not use this code, it will be removed in future bk_mrs_project_file = NULL; keyboard_bk_mrs_project_act = new QAction(this); keyboard_bk_mrs_project_act->setShortcut(Qt::Key_P); this->addAction(keyboard_bk_mrs_project_act); connect(keyboard_bk_mrs_project_act, SIGNAL(triggered()), this, SLOT(keyboard_bk_mrs_project_func())); #endif save_act = new QAction("Save as", this); save_act->setShortcut(QKeySequence::Save); save_act->setEnabled(FALSE); connect(save_act, SIGNAL(triggered()), this, SLOT(save_file())); filemenu = new QMenu(this); filemenu->setTitle("&File"); filemenu->addAction("Open", this, SLOT(open_new_file()), QKeySequence::Open); filemenu->addSeparator(); filemenu->addAction("Open stream", this, SLOT(open_stream())); filemenu->addSeparator(); filemenu->addAction(save_act); filemenu->addMenu(recent_filesmenu); filemenu->addMenu(printmenu); filemenu->addAction("Info", this, SLOT(show_file_info())); filemenu->addAction("Close all", this, SLOT(close_all_files()), QKeySequence::Close); filemenu->addAction("Exit", this, SLOT(exit_program()), QKeySequence::Quit); menubar->addMenu(filemenu); signalmenu = new QMenu(this); signalmenu->setTitle("&Signals"); signalmenu->addAction("Properties", this, SLOT(signalproperties_dialog())); signalmenu->addAction("Add", this, SLOT(add_signals_dialog())); signalmenu->addAction("Organize", this, SLOT(organize_signals())); signalmenu->addAction("Remove all", this, SLOT(remove_all_signals())); menubar->addMenu(signalmenu); displaymenu = new QMenu(this); displaymenu->setTitle("&Timescale"); displaymenu->addAction("3 cm/sec", this, SLOT(page_3cmsec())); displaymenu->addSeparator(); page_10m = new QAction("10 mSec/page", this); displaymenu->addAction(page_10m); page_20m = new QAction("20 mSec/page", this); displaymenu->addAction(page_20m); page_50m = new QAction("50 mSec/page", this); displaymenu->addAction(page_50m); page_100m = new QAction("100 mSec/page", this); displaymenu->addAction(page_100m); page_200m = new QAction("200 mSec/page", this); displaymenu->addAction(page_200m); page_500m = new QAction("500 mSec/page", this); displaymenu->addAction(page_500m); page_1 = new QAction("1 Sec/page", this); displaymenu->addAction(page_1); page_2 = new QAction("2 Sec/page", this); displaymenu->addAction(page_2); page_5 = new QAction("5 Sec/page", this); displaymenu->addAction(page_5); page_10 = new QAction("10 Sec/page", this); displaymenu->addAction(page_10); page_15 = new QAction("15 Sec/page", this); displaymenu->addAction(page_15); page_20 = new QAction("20 Sec/page", this); displaymenu->addAction(page_20); page_30 = new QAction("30 Sec/page", this); page_30->setChecked(TRUE); displaymenu->addAction(page_30); page_60 = new QAction("60 Sec/page", this); displaymenu->addAction(page_60); page_300 = new QAction("5 min/page", this); displaymenu->addAction(page_300); page_1200 = new QAction("20 min/page", this); displaymenu->addAction(page_1200); page_3600 = new QAction("1 hour/page", this); displaymenu->addAction(page_3600); displaymenu->addSeparator(); page_div2 = new QAction("Timescale / 2", this); page_div2->setShortcut(QKeySequence::ZoomIn); connect(page_div2, SIGNAL(triggered()), this, SLOT(set_page_div2())); displaymenu->addAction(page_div2); page_mult2 = new QAction("Timescale x 2", this); page_mult2->setShortcut(QKeySequence::ZoomOut); connect(page_mult2, SIGNAL(triggered()), this, SLOT(set_page_mult2())); displaymenu->addAction(page_mult2); displaymenu->addSeparator(); page_user_defined = new QAction("user defined", this); connect(page_user_defined, SIGNAL(triggered()), this, SLOT(set_user_defined_display_time())); displaymenu->addAction(page_user_defined); displaymenu->addSeparator(); page_whole_rec = new QAction("whole recording", this); connect(page_whole_rec, SIGNAL(triggered()), this, SLOT(set_display_time_whole_rec())); displaymenu->addAction(page_whole_rec); menubar->addMenu(displaymenu); DisplayGroup = new QActionGroup(this); DisplayGroup->addAction(page_10m); DisplayGroup->addAction(page_20m); DisplayGroup->addAction(page_50m); DisplayGroup->addAction(page_100m); DisplayGroup->addAction(page_200m); DisplayGroup->addAction(page_500m); DisplayGroup->addAction(page_1); DisplayGroup->addAction(page_2); DisplayGroup->addAction(page_5); DisplayGroup->addAction(page_10); DisplayGroup->addAction(page_15); DisplayGroup->addAction(page_20); DisplayGroup->addAction(page_30); DisplayGroup->addAction(page_60); DisplayGroup->addAction(page_300); DisplayGroup->addAction(page_1200); DisplayGroup->addAction(page_3600); connect(DisplayGroup, SIGNAL(triggered(QAction *)), this, SLOT(set_display_time(QAction *))); amplitudemenu = new QMenu(this); amplitudemenu->setTitle("&Amplitude"); fit_to_pane = new QAction("Fit to pane", this); connect(fit_to_pane, SIGNAL(triggered()), this, SLOT(fit_signals_to_pane())); amplitudemenu->addAction(fit_to_pane); fit_to_dc = new QAction("Adjust offset", this); connect(fit_to_dc, SIGNAL(triggered()), this, SLOT(fit_signals_dc_offset())); amplitudemenu->addAction(fit_to_dc); amplitudemenu->addAction("Offset -> 0", this, SLOT(set_dc_offset_to_zero())); amplitudemenu->addSeparator(); amp_50000 = new QAction("50000", this); amplitudemenu->addAction(amp_50000); amp_20000 = new QAction("20000", this); amplitudemenu->addAction(amp_20000); amp_10000 = new QAction("10000", this); amplitudemenu->addAction(amp_10000); amp_5000 = new QAction("5000", this); amplitudemenu->addAction(amp_5000); amp_2000 = new QAction("2000", this); amplitudemenu->addAction(amp_2000); amp_1000 = new QAction("1000", this); amplitudemenu->addAction(amp_1000); amp_500 = new QAction("500", this); amplitudemenu->addAction(amp_500); amp_200 = new QAction("200", this); amplitudemenu->addAction(amp_200); amp_100 = new QAction("100 (50uV/5mm)", this); amplitudemenu->addAction(amp_100); amp_50 = new QAction("50", this); amplitudemenu->addAction(amp_50); amp_20 = new QAction("20", this); amplitudemenu->addAction(amp_20); amp_10 = new QAction("10", this); amplitudemenu->addAction(amp_10); amp_5 = new QAction("5", this); amplitudemenu->addAction(amp_5); amp_2 = new QAction("2", this); amplitudemenu->addAction(amp_2); amp_1 = new QAction("1", this); amplitudemenu->addAction(amp_1); amp_05 = new QAction("0.5", this); amplitudemenu->addAction(amp_05); amp_02 = new QAction("0.2", this); amplitudemenu->addAction(amp_02); amp_01 = new QAction("0.1", this); amplitudemenu->addAction(amp_01); amp_005 = new QAction("0.05", this); amplitudemenu->addAction(amp_005); amp_002 = new QAction("0.02", this); amplitudemenu->addAction(amp_002); amp_001 = new QAction("0.01", this); amplitudemenu->addAction(amp_001); amp_0005 = new QAction("0.005", this); amplitudemenu->addAction(amp_0005); amp_0002 = new QAction("0.002", this); amplitudemenu->addAction(amp_0002); amp_0001 = new QAction("0.001", this); amplitudemenu->addAction(amp_0001); amp_00005 = new QAction("0.0005", this); amplitudemenu->addAction(amp_00005); amp_00002 = new QAction("0.0002", this); amplitudemenu->addAction(amp_00002); amp_00001 = new QAction("0.0001", this); amplitudemenu->addAction(amp_00001); amplitudemenu->addSeparator(); amp_plus = new QAction("Amplitude x 2", this); amp_plus->setShortcut(Qt::Key_Minus); connect(amp_plus, SIGNAL(triggered()), this, SLOT(set_amplitude_mult2())); amplitudemenu->addAction(amp_plus); amp_minus = new QAction("Amplitude / 2", this); amp_minus->setShortcut(Qt::Key_Plus); connect(amp_minus, SIGNAL(triggered()), this, SLOT(set_amplitude_div2())); amplitudemenu->addAction(amp_minus); menubar->addMenu(amplitudemenu); AmplitudeGroup = new QActionGroup(this); AmplitudeGroup->addAction(amp_00001); AmplitudeGroup->addAction(amp_00002); AmplitudeGroup->addAction(amp_00005); AmplitudeGroup->addAction(amp_0001); AmplitudeGroup->addAction(amp_0002); AmplitudeGroup->addAction(amp_0005); AmplitudeGroup->addAction(amp_001); AmplitudeGroup->addAction(amp_002); AmplitudeGroup->addAction(amp_005); AmplitudeGroup->addAction(amp_01); AmplitudeGroup->addAction(amp_02); AmplitudeGroup->addAction(amp_05); AmplitudeGroup->addAction(amp_1); AmplitudeGroup->addAction(amp_2); AmplitudeGroup->addAction(amp_5); AmplitudeGroup->addAction(amp_10); AmplitudeGroup->addAction(amp_20); AmplitudeGroup->addAction(amp_50); AmplitudeGroup->addAction(amp_100); AmplitudeGroup->addAction(amp_200); AmplitudeGroup->addAction(amp_500); AmplitudeGroup->addAction(amp_1000); AmplitudeGroup->addAction(amp_2000); AmplitudeGroup->addAction(amp_5000); AmplitudeGroup->addAction(amp_10000); AmplitudeGroup->addAction(amp_20000); AmplitudeGroup->addAction(amp_50000); connect(AmplitudeGroup, SIGNAL(triggered(QAction *)), this, SLOT(set_amplitude(QAction *))); filtermenu = new QMenu(this); filtermenu->setTitle("&Filter"); filtermenu->addAction("New", this, SLOT(add_new_filter())); filtermenu->addAction("Adjust", this, SLOT(filterproperties_dialog())); filtermenu->addAction("Remove all", this, SLOT(remove_all_filters())); menubar->addMenu(filtermenu); // math_func_menu = new QMenu(this); // math_func_menu->setTitle("&Math"); // math_func_menu->addAction("New", this, SLOT(add_new_math_func())); // math_func_menu->addAction("Remove all", this, SLOT(remove_all_math_funcs())); // menubar->addMenu(math_func_menu); load_predefined_mtg_act[0] = new QAction("Empty", this); load_predefined_mtg_act[0]->setShortcut(Qt::Key_F1); load_predefined_mtg_act[1] = new QAction("Empty", this); load_predefined_mtg_act[1]->setShortcut(Qt::Key_F2); load_predefined_mtg_act[2] = new QAction("Empty", this); load_predefined_mtg_act[2]->setShortcut(Qt::Key_F3); load_predefined_mtg_act[3] = new QAction("Empty", this); load_predefined_mtg_act[3]->setShortcut(Qt::Key_F4); load_predefined_mtg_act[4] = new QAction("Empty", this); load_predefined_mtg_act[4]->setShortcut(Qt::Key_F5); load_predefined_mtg_act[5] = new QAction("Empty", this); load_predefined_mtg_act[5]->setShortcut(Qt::Key_F6); load_predefined_mtg_act[6] = new QAction("Empty", this); load_predefined_mtg_act[6]->setShortcut(Qt::Key_F7); load_predefined_mtg_act[7] = new QAction("Empty", this); load_predefined_mtg_act[7]->setShortcut(Qt::Key_F8); load_predefined_mtg_act[8] = new QAction("Empty", this); load_predefined_mtg_act[8]->setShortcut(Qt::Key_F9); load_predefined_mtg_act[9] = new QAction("Empty", this); load_predefined_mtg_act[9]->setShortcut(Qt::Key_F10); load_predefined_mtg_act[10] = new QAction("Empty", this); load_predefined_mtg_act[10]->setShortcut(Qt::Key_F11); load_predefined_mtg_act[11] = new QAction("Empty", this); load_predefined_mtg_act[11]->setShortcut(Qt::Key_F12); load_predefined_mtg_group = new QActionGroup(this); for(i=0; i < MAXPREDEFINEDMONTAGES; i++) { load_predefined_mtg_group->addAction(load_predefined_mtg_act[i]); } connect(load_predefined_mtg_group, SIGNAL(triggered(QAction *)), this, SLOT(load_predefined_mtg(QAction *))); montagemenu = new QMenu(this); montagemenu->setTitle("&Montage"); montagemenu->addAction("View this montage", this, SLOT(show_this_montage())); montagemenu->addAction("View saved montages", this, SLOT(view_montage())); montagemenu->addAction("Save", this, SLOT(save_montage())); montagemenu->addAction("Load", this, SLOT(load_montage())); montagemenu->addSeparator(); montagemenu->addAction("Edit key-bindings for montages", this, SLOT(edit_predefined_montages())); montagemenu->addSeparator(); for(i=0; i < MAXPREDEFINEDMONTAGES; i++) { montagemenu->addAction(load_predefined_mtg_act[i]); } menubar->addMenu(montagemenu); // patternmenu = new QMenu(this); // patternmenu->setTitle("&Pattern"); // patternmenu->addAction("Search", this, SLOT(search_pattern())); // menubar->addMenu(patternmenu); toolsmenu = new QMenu(this); toolsmenu->setTitle("T&ools"); toolsmenu->addAction("Check EDF/BDF compatibility", this, SLOT(check_edf_compatibility())); toolsmenu->addSeparator(); toolsmenu->addAction("Header editor", this, SLOT(edit_header())); toolsmenu->addAction("Reduce signals, duration or samplerate", this, SLOT(reduce_signals())); toolsmenu->addAction("Remove duplicates in annotations", this, SLOT(edfplus_annotation_remove_duplicates())); toolsmenu->addSeparator(); toolsmenu->addAction("Import annotations/events", this, SLOT(import_annotations())); toolsmenu->addAction("Export annotations/events", this, SLOT(export_annotations())); toolsmenu->addAction("Export EDF/BDF to ASCII", this, SLOT(export_to_ascii())); toolsmenu->addAction("Export/Import ECG RR-interval", this, SLOT(export_ecg_rr_interval_to_ascii())); toolsmenu->addSeparator(); toolsmenu->addAction("Convert Nihon Kohden to EDF+", this, SLOT(nk2edf_converter())); toolsmenu->addAction("Convert ASCII to EDF/BDF", this, SLOT(convert_ascii_to_edf())); toolsmenu->addAction("Convert Manscan to EDF+", this, SLOT(convert_manscan_to_edf())); toolsmenu->addAction("Convert SCP ECG to EDF+", this, SLOT(convert_scpecg_to_edf())); toolsmenu->addAction("Convert Finometer to EDF", this, SLOT(convert_fino_to_edf())); toolsmenu->addAction("Convert Nexfin to EDF", this, SLOT(convert_nexfin_to_edf())); toolsmenu->addAction("Convert Emsa to EDF+", this, SLOT(convert_emsa_to_edf())); toolsmenu->addAction("Convert EDF+D to EDF+C", this, SLOT(edfd_converter())); toolsmenu->addAction("Convert Biosemi to BDF+", this, SLOT(biosemi2bdfplus_converter())); toolsmenu->addAction("Convert BDF to EDF", this, SLOT(bdf2edf_converter())); toolsmenu->addAction("Convert Unisens to EDF+", this, SLOT(unisens2edf_converter())); toolsmenu->addAction("Convert BI9800TL+3 to EDF", this, SLOT(BI98002edf_converter())); toolsmenu->addAction("Convert Wave to EDF", this, SLOT(convert_wave_to_edf())); toolsmenu->addAction("Convert Binary/raw data to EDF", this, SLOT(convert_binary_to_edf())); toolsmenu->addSeparator(); toolsmenu->addAction("Options", this, SLOT(show_options_dialog())); menubar->addMenu(toolsmenu); menubar->addAction("S&ettings", this, SLOT(show_options_dialog())); former_page_Act = new QAction("<<", this); former_page_Act->setShortcut(QKeySequence::MoveToPreviousPage); connect(former_page_Act, SIGNAL(triggered()), this, SLOT(former_page())); menubar->addAction(former_page_Act); shift_page_left_Act = new QAction("<", this); shift_page_left_Act->setShortcut(QKeySequence::MoveToPreviousChar); connect(shift_page_left_Act, SIGNAL(triggered()), this, SLOT(shift_page_left())); menubar->addAction(shift_page_left_Act); shift_page_right_Act = new QAction(">", this); shift_page_right_Act->setShortcut(QKeySequence::MoveToNextChar); connect(shift_page_right_Act, SIGNAL(triggered()), this, SLOT(shift_page_right())); menubar->addAction(shift_page_right_Act); next_page_Act = new QAction(">>", this); next_page_Act->setShortcut(QKeySequence::MoveToNextPage); connect(next_page_Act, SIGNAL(triggered()), this, SLOT(next_page())); menubar->addAction(next_page_Act); shift_page_up_Act = new QAction("^", this); shift_page_up_Act->setShortcut(QKeySequence::MoveToPreviousLine); connect(shift_page_up_Act, SIGNAL(triggered()), this, SLOT(shift_page_up())); menubar->addAction(shift_page_up_Act); shift_page_down_Act = new QAction("v", this); shift_page_down_Act->setShortcut(QKeySequence::MoveToNextLine); connect(shift_page_down_Act, SIGNAL(triggered()), this, SLOT(shift_page_down())); menubar->addAction(shift_page_down_Act); zoomback_Act = new QAction("zoomback", this); zoomback_Act->setShortcut(Qt::Key_Backspace); connect(zoomback_Act, SIGNAL(triggered()), this, SLOT(zoomback())); menubar->addAction(zoomback_Act); zoomforward_Act = new QAction("zoomforward", this); zoomforward_Act->setShortcut(Qt::Key_Insert); connect(zoomforward_Act, SIGNAL(triggered()), this, SLOT(forward())); menubar->addAction(zoomforward_Act); no_timesync_act = new QAction("no timelock", this); no_timesync_act->setCheckable(TRUE); offset_timesync_act = new QAction("synchronize start of files (offset)", this); offset_timesync_act->setCheckable(TRUE); absolut_timesync_act = new QAction("synchronize absolute time", this); absolut_timesync_act->setCheckable(TRUE); user_def_sync_act = new QAction("user defined synchronizing", this); user_def_sync_act->setCheckable(TRUE); timelock_act_group = new QActionGroup(this); timelock_act_group->addAction(no_timesync_act); timelock_act_group->addAction(offset_timesync_act); timelock_act_group->addAction(absolut_timesync_act); timelock_act_group->addAction(user_def_sync_act); absolut_timesync_act->setChecked(TRUE); connect(timelock_act_group, SIGNAL(triggered(QAction *)), this, SLOT(set_timesync(QAction *))); sel_viewtime_act_group = new QActionGroup(this); connect(sel_viewtime_act_group, SIGNAL(triggered(QAction *)), this, SLOT(set_timesync_reference(QAction *))); timemenu = new QMenu(this); timemenu->setTitle("T&imesync"); timemenu->addAction("Go to start of file", this, SLOT(jump_to_start()), QKeySequence::MoveToStartOfDocument); timemenu->addAction("Go to end of file", this, SLOT(jump_to_end()), QKeySequence::MoveToEndOfDocument); timemenu->addAction("Jump to", this, SLOT(jump_to_dialog())); timemenu->addSeparator()->setText("Timelock"); timemenu->addAction(no_timesync_act); timemenu->addAction(offset_timesync_act); timemenu->addAction(absolut_timesync_act); timemenu->addAction(user_def_sync_act); timemenu->addSeparator(); timemenu->addAction("synchronize by crosshairs", this, SLOT(sync_by_crosshairs())); timemenu->addSeparator()->setText("Time reference"); menubar->addMenu(timemenu); windowmenu = new QMenu(this); windowmenu->setTitle("&Window"); windowmenu->addAction("Annotations", this, SLOT(show_annotations())); windowmenu->addAction("Annotation editor", this, SLOT(annotation_editor())); windowmenu->addAction("Spectrum", this, SLOT(show_spectrum_dock())); menubar->addMenu(windowmenu); helpmenu = new QMenu(this); helpmenu->setTitle("&Help"); #ifdef Q_WS_X11 helpmenu->addAction("Manual", this, SLOT(show_help())); #endif #ifdef Q_WS_WIN helpmenu->addAction("Manual", this, SLOT(show_help())); #endif helpmenu->addAction("Keyboard shortcuts", this, SLOT(show_kb_shortcuts())); helpmenu->addAction("About EDFbrowser", this, SLOT(show_about_dialog())); helpmenu->addAction("Show splashscreen", this, SLOT(show_splashscreen())); menubar->addMenu(helpmenu); Escape_act = new QAction(this); Escape_act->setShortcut(Qt::Key_Escape); connect(Escape_act, SIGNAL(triggered()), this, SLOT(Escape_fun())); maincurve->addAction(Escape_act); positionslider = new QSlider(Qt::Horizontal); positionslider->setRange(0, 1000000); positionslider->setSingleStep(10000); positionslider->setPageStep(100000); slidertoolbar = new QToolBar(); slidertoolbar->setFloatable(FALSE); slidertoolbar->setAllowedAreas(Qt::TopToolBarArea | Qt::BottomToolBarArea); slidertoolbar->addWidget(positionslider); addToolBar(Qt::BottomToolBarArea, slidertoolbar); QObject::connect(positionslider, SIGNAL(valueChanged(int)), this, SLOT(slider_moved(int))); slidertoolbar->setEnabled(FALSE); positionslider->blockSignals(TRUE); files_open = 0; signalcomps = 0; sel_viewtime = 0; viewtime_sync = VIEWTIME_SYNCED_ABSOLUT; pagetime = 10 * TIME_DIMENSION; viewtime_string[0] = 0; pagetime_string[0] = 0; totalviewbufsize = 0; print_to_edf_active = 0; annot_editor_active = 0; annotations_edited = 0; viewbuf = NULL; for(i=0; ihistory_size_tail = 0; zoomhistory->history_size_front = 0; for(i=0; i<64; i++) { zoomhistory->pntr = 0; zoomhistory->pagetime[i] = 10 * TIME_DIMENSION; for(j=0; jviewtime[i][j] = 0; } for(j=0; jvoltpercm[i][j] = 70.0; zoomhistory->screen_offset[i][j] = 0.0; for(k=0; ksensitivity[i][j][k] = 0.0475; } } } path[0] = 0; recent_montagedir[0] = 0; recent_savedir[0] = 0; recent_opendir[0] = 0; montagepath[0] = 0; for(i=0; isetText(predefined_mtg_path[i]); } } annotationEditDock = new UI_AnnotationEditwindow(files_open, this); addDockWidget(Qt::BottomDockWidgetArea, annotationEditDock->dockedit, Qt::Horizontal); annotationEditDock->dockedit->hide(); spectrumdock = new UI_SpectrumDockWindow(this); addDockWidget(Qt::TopDockWidgetArea, spectrumdock->dock, Qt::Horizontal); spectrumdock->dock->hide(); setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea); setCorner(Qt::TopRightCorner, Qt::RightDockWidgetArea); setCorner(Qt::BottomLeftCorner, Qt::BottomDockWidgetArea); setCorner(Qt::BottomRightCorner, Qt::BottomDockWidgetArea); if(QCoreApplication::arguments().size()>1) { strcpy(path, QCoreApplication::arguments().at(1).toLocal8Bit().data()); cmdlineargument = 1; if(QCoreApplication::arguments().size()>2) { strcpy(montagepath, QCoreApplication::arguments().at(2).toLocal8Bit().data()); cmdlineargument = 2; } } else { cmdlineargument = 0; } showMaximized(); oldwindowheight = height(); if(cmdlineargument) { open_new_file(); } if(QT_VERSION < MINIMUM_QT_VERSION) { QMessageBox messagewindow(QMessageBox::Warning, "Warning", "Qt version is too old"); messagewindow.exec(); } else { int v_nr; char v_str[32]; strncpy(v_str, qVersion(), 32); v_str[31] = 0; v_nr = 0x10000 * atoi(v_str); v_nr += 0x100 * atoi(v_str + 2); v_nr += atoi(v_str + 4); if(v_nr < MINIMUM_QT_VERSION) { QMessageBox messagewindow(QMessageBox::Warning, "Warning", "Qt version is too old"); messagewindow.exec(); } } pixmap = new QPixmap(":/images/splash.png"); splash = new QSplashScreen(this, *pixmap, Qt::WindowStaysOnTopHint); update_checker = NULL; if(check_for_updates) { update_checker = new Check_for_updates; } } UI_Mainwindow::~UI_Mainwindow() { delete pixmap; delete splash; delete myfont; delete monofont; delete maincurve; delete annotationEditDock; delete spectrumdock; delete live_stream_timer; if(update_checker != NULL) delete update_checker; } void UI_Mainwindow::exit_program() { close(); } void UI_Mainwindow::closeEvent(QCloseEvent *cl_event) { int i, button_nr=0; if(annotations_edited) { QMessageBox messagewindow; messagewindow.setText("There are unsaved annotations,\n are you sure you want to quit?"); messagewindow.setIcon(QMessageBox::Question); messagewindow.setStandardButtons(QMessageBox::Cancel | QMessageBox::Close); messagewindow.setDefaultButton(QMessageBox::Cancel); button_nr = messagewindow.exec(); } if(button_nr == QMessageBox::Cancel) { cl_event->ignore(); } else { exit_in_progress = 1; for(i=0; iaccept(); } } // void UI_Mainwindow::search_pattern() // { // if(!signalcomps) // { // return; // } // // // // } void UI_Mainwindow::Escape_fun() { int i; for(i=0; ihascursor1 = 0; signalcomp[i]->hascursor2 = 0; signalcomp[i]->hasoffsettracking = 0; } maincurve->crosshair_1.active = 0; maincurve->crosshair_2.active = 0; maincurve->crosshair_1.moving = 0; maincurve->crosshair_2.moving = 0; maincurve->use_move_events = 0; maincurve->setMouseTracking(FALSE); for(i=0; ihasruler = 0; } maincurve->ruler_active = 0; maincurve->ruler_moving = 0; maincurve->update(); } void UI_Mainwindow::open_stream() { if(files_open) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Close all files before opening a stream."); messagewindow.exec(); return; } live_stream_active = 1; open_new_file(); if(files_open == 1) { toolsmenu->setEnabled(FALSE); timemenu->setEnabled(FALSE); windowmenu->setEnabled(FALSE); former_page_Act->setEnabled(FALSE); shift_page_left_Act->setEnabled(FALSE); shift_page_right_Act->setEnabled(FALSE); next_page_Act->setEnabled(FALSE); shift_page_up_Act->setEnabled(FALSE); shift_page_down_Act->setEnabled(FALSE); printmenu->setEnabled(FALSE); recent_filesmenu->setEnabled(FALSE); live_stream_timer->start(live_stream_update_interval); } else { live_stream_active = 0; } } void UI_Mainwindow::live_stream_timer_func() { long long datarecords_old, datarecords_new; if((!live_stream_active) || (files_open != 1)) { return; } if(!signalcomps) { live_stream_timer->start(live_stream_update_interval); return; } datarecords_old = edfheaderlist[0]->datarecords; datarecords_new = check_edf_file_datarecords(edfheaderlist[0]); if(datarecords_new == 0LL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Stream has no datarecords."); messagewindow.exec(); close_all_files(); return; } if((datarecords_new > datarecords_old) && (datarecords_new > 0)) { jump_to_end(); } live_stream_timer->start(live_stream_update_interval); } long long UI_Mainwindow::check_edf_file_datarecords(struct edfhdrblock *hdr) { long long datarecords; if(fseeko(hdr->file_hdl, 0LL, SEEK_END) == -1LL) { hdr->datarecords = 0LL; return(0LL); } datarecords = ftello(hdr->file_hdl); if(datarecords < 1LL) { hdr->datarecords = 0LL; return(0LL); } datarecords -= (long long)hdr->hdrsize; datarecords /= (long long)hdr->recordsize; if(datarecords < 1LL) { hdr->datarecords = 0LL; return(0LL); } hdr->datarecords = datarecords; return(datarecords); } #ifdef BK_MRS_project // temporary code for private use in a certain project // do not use this code, it will be removed in future void UI_Mainwindow::keyboard_bk_mrs_project_func() { int i, j, len, type, model, order, file_present=0; char path[MAX_PATH_LENGTH], str_signal[1024], str_dimension[32]; double result_mrs, result_rms, frequency, frequency2, ripple; struct edfhdrblock *hdr; hdr = edfheaderlist[0]; if((!files_open) || (!signalcomps)) { return; } if(bk_mrs_project_file == NULL) { get_filename_from_path(path, hdr->filename, MAX_PATH_LENGTH); remove_extension_from_filename(path); strcat(path, "_mrs.txt"); strcpy(path, QFileDialog::getSaveFileName(0, "MRS output file", QString::fromLocal8Bit(path), "Text files (*.txt *.TXT)").toLocal8Bit().data()); if(!strcmp(path, "")) { return; } bk_mrs_project_file = fopeno(path, "rb"); if(bk_mrs_project_file != NULL) { fclose(bk_mrs_project_file); bk_mrs_project_file = NULL; file_present = 1; } if(file_present) { bk_mrs_project_file = fopeno(path, "ab"); } else { bk_mrs_project_file = fopeno(path, "wb"); } if(bk_mrs_project_file == NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not open outputfile for writing."); messagewindow.exec(); return; } if(!file_present) { fprintf(bk_mrs_project_file, "starttime,pagetime,signal,number_of_samples,mrs,rms,physical_dimension,file,\n"); } } for(i=0; isignallabel); len = strlen(str_signal); for(j=0; jstat_cnt) { result_mrs = (signalcomp[i]->stat_sum_rectified / signalcomp[i]->stat_cnt) * signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].bitvalue; result_rms = sqrt(signalcomp[i]->stat_sum_sqr / signalcomp[i]->stat_cnt) * signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].bitvalue; } else { result_mrs = 0.0; result_rms = 0.0; } strcpy(str_dimension, signalcomp[i]->physdimension); len = strlen(str_dimension); for(j=0; jviewtime / TIME_DIMENSION, hdr->viewtime % TIME_DIMENSION, pagetime / TIME_DIMENSION, pagetime % TIME_DIMENSION, str_signal, signalcomp[i]->stat_cnt, result_mrs, result_rms, str_dimension); #else fprintf(bk_mrs_project_file, "%lli.%07lli,%lli.%07lli,%s,%i,%f,%f,%s", hdr->viewtime / TIME_DIMENSION, hdr->viewtime % TIME_DIMENSION, pagetime / TIME_DIMENSION, pagetime % TIME_DIMENSION, str_signal, signalcomp[i]->stat_cnt, result_mrs, result_rms, str_dimension); #endif fprintf(bk_mrs_project_file, ",%s", hdr->filename); for(j=0; jfidfilter_cnt; j++) { type = signalcomp[i]->fidfilter_type[j]; model = signalcomp[i]->fidfilter_model[j]; frequency = signalcomp[i]->fidfilter_freq[j]; frequency2 = signalcomp[i]->fidfilter_freq2[j]; order = signalcomp[i]->fidfilter_order[j]; ripple = signalcomp[i]->fidfilter_ripple[j]; if(type == 0) { fprintf(bk_mrs_project_file, ",HP"); } if(type == 1) { fprintf(bk_mrs_project_file, ",LP"); } if(type == 2) { fprintf(bk_mrs_project_file, ",N Res %fHz Q-factor %i", frequency, order); } if(type == 3) { fprintf(bk_mrs_project_file, ",BP"); } if(type == 4) { fprintf(bk_mrs_project_file, ",BS"); } if(type != 2) { if(model == 0) { fprintf(bk_mrs_project_file, " Bu"); } if(model == 1) { fprintf(bk_mrs_project_file, " Ch"); } if(model == 2) { fprintf(bk_mrs_project_file, " Be"); } if((type == 0) || (type == 1)) { fprintf(bk_mrs_project_file, " %fHz %ith order", frequency, order); } if((type == 3) || (type == 4)) { fprintf(bk_mrs_project_file, " %f-%fHz %ith order", frequency, frequency2, order); } if(model == 1) { fprintf(bk_mrs_project_file, " ripple %fdB", ripple); } } } fputc('\n', bk_mrs_project_file); } fflush(bk_mrs_project_file); UI_Messagewindow popupmessage("Message", "Values are written.", NULL, 1000); } #endif void UI_Mainwindow::save_file() { int len; char f_path[MAX_PATH_LENGTH]; struct edfhdrblock *hdr; struct annotationblock *annot; FILE *outputfile; if((!annotations_edited)||(!files_open)) { save_act->setEnabled(FALSE); return; } hdr = edfheaderlist[0]; strcpy(f_path, recent_savedir); strcat(f_path, "/"); len = strlen(f_path); get_filename_from_path(f_path + len, hdr->filename, MAX_PATH_LENGTH - len); remove_extension_from_filename(f_path); if(hdr->edf) { strcat(f_path, "_edited.edf"); } else { strcat(f_path, "_edited.bdf"); } strcpy(f_path, QFileDialog::getSaveFileName(this, "Save file", QString::fromLocal8Bit(f_path), "EDF/BDF files (*.edf *.EDF *.bdf *.BDF *.rec *.REC)").toLocal8Bit().data()); if(!strcmp(f_path, "")) { return; } get_directory_from_path(recent_savedir, f_path, MAX_PATH_LENGTH); if(file_is_opened(f_path)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Selected file is in use."); messagewindow.exec(); return; } outputfile = fopeno(f_path, "wb"); if(outputfile==NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not create a file for writing."); messagewindow.exec(); return; } if(save_annotations(this, outputfile, hdr, annotationlist[0])) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred during saving."); messagewindow.exec(); fclose(outputfile); return; } fclose(outputfile); annot = annotationlist[0]; annotationlist[0] = annotationlist_backup; annotationlist_backup = NULL; edfplus_annotation_delete_list(&annot); annotations_dock[0]->updateList(); annotations_edited = 0; save_act->setEnabled(FALSE); annotationEditDock->dockedit->hide(); maincurve->update(); } void UI_Mainwindow::slider_moved(int value) { int i; long long new_viewtime, tmp; if(!signalcomps) return; new_viewtime = edfheaderlist[sel_viewtime]->long_data_record_duration * edfheaderlist[sel_viewtime]->datarecords; new_viewtime -= pagetime; if(new_viewtime<0) { new_viewtime = 0; } else { new_viewtime /= 1000000; new_viewtime *= value; } if(pagetime >= (300LL * TIME_DIMENSION)) { tmp = new_viewtime % (30LL * TIME_DIMENSION); new_viewtime -= tmp; } else if(pagetime >= (60LL * TIME_DIMENSION)) { tmp = new_viewtime % (6LL * TIME_DIMENSION); new_viewtime -= tmp; } else if(pagetime >= (30LL * TIME_DIMENSION)) { tmp = new_viewtime % (3LL * TIME_DIMENSION); new_viewtime -= tmp; } else if(pagetime >= (20LL * TIME_DIMENSION)) { tmp = new_viewtime % (2LL * TIME_DIMENSION); new_viewtime -= tmp; } else if(pagetime >= (10LL * TIME_DIMENSION)) { tmp = new_viewtime % TIME_DIMENSION; new_viewtime -= tmp; } else if(pagetime >= TIME_DIMENSION) { tmp = new_viewtime % (TIME_DIMENSION / 10LL); new_viewtime -= tmp; } if(viewtime_sync==VIEWTIME_SYNCED_OFFSET) { for(i=0; iviewtime = new_viewtime; } } if(viewtime_sync==VIEWTIME_UNSYNCED) { edfheaderlist[sel_viewtime]->viewtime = new_viewtime; } if(viewtime_sync==VIEWTIME_SYNCED_ABSOLUT) { edfheaderlist[sel_viewtime]->viewtime = new_viewtime; for(i=0; iviewtime = edfheaderlist[sel_viewtime]->viewtime - ((edfheaderlist[i]->utc_starttime - edfheaderlist[sel_viewtime]->utc_starttime) * TIME_DIMENSION); } } } if(viewtime_sync==VIEWTIME_USER_DEF_SYNCED) { for(i=0; iviewtime -= (edfheaderlist[sel_viewtime]->viewtime - new_viewtime); } } edfheaderlist[sel_viewtime]->viewtime = new_viewtime; } setup_viewbuf(); } void UI_Mainwindow::set_timesync_reference(QAction *action) { int i; for(i=0; ifilename, action->text().toLocal8Bit().data())) { break; } } sel_viewtime = i; setMainwindowTitle(edfheaderlist[sel_viewtime]); setup_viewbuf(); } void UI_Mainwindow::set_timesync(QAction *) { int i; if(no_timesync_act->isChecked()) { viewtime_sync = VIEWTIME_UNSYNCED; } if(offset_timesync_act->isChecked()) { viewtime_sync = VIEWTIME_SYNCED_OFFSET; for(i=0; iviewtime = edfheaderlist[sel_viewtime]->viewtime; } } if(absolut_timesync_act->isChecked()) { viewtime_sync = VIEWTIME_SYNCED_ABSOLUT; for(i=0; iviewtime = edfheaderlist[sel_viewtime]->viewtime + edfheaderlist[sel_viewtime]->starttime_offset - ((edfheaderlist[i]->utc_starttime - edfheaderlist[sel_viewtime]->utc_starttime) * TIME_DIMENSION) - edfheaderlist[i]->starttime_offset; } } } if(user_def_sync_act->isChecked()) { viewtime_sync = VIEWTIME_USER_DEF_SYNCED; } setup_viewbuf(); } void UI_Mainwindow::sync_by_crosshairs() { if(files_open<2) return; if(signalcomps<2) return; if(maincurve->crosshair_1.active&&maincurve->crosshair_2.active) { if(maincurve->crosshair_1.file_num!=maincurve->crosshair_2.file_num) { viewtime_sync = VIEWTIME_USER_DEF_SYNCED; edfheaderlist[maincurve->crosshair_2.file_num]->viewtime -= ((maincurve->crosshair_1.time - edfheaderlist[maincurve->crosshair_1.file_num]->l_starttime - edfheaderlist[maincurve->crosshair_1.file_num]->viewtime - edfheaderlist[maincurve->crosshair_1.file_num]->starttime_offset) - (maincurve->crosshair_2.time - edfheaderlist[maincurve->crosshair_2.file_num]->l_starttime - edfheaderlist[maincurve->crosshair_2.file_num]->viewtime - edfheaderlist[maincurve->crosshair_2.file_num]->starttime_offset)); maincurve->crosshair_2.x_position = maincurve->crosshair_1.x_position; user_def_sync_act->setChecked(TRUE); viewtime_sync = VIEWTIME_USER_DEF_SYNCED; setup_viewbuf(); } } } void UI_Mainwindow::show_options_dialog() { UI_OptionsDialog OptionsDialog(this); } void UI_Mainwindow::nk2edf_converter() { UI_NK2EDFwindow nk2edf(recent_opendir); } void UI_Mainwindow::convert_ascii_to_edf() { UI_ASCII2EDFapp ascii2edf(recent_opendir, recent_savedir); } void UI_Mainwindow::convert_binary_to_edf() { UI_RAW2EDFapp bin2edf(&raw2edf_var, recent_opendir, recent_savedir); } void UI_Mainwindow::convert_fino_to_edf() { UI_FINO2EDFwindow fino2edf(recent_opendir, recent_savedir); } void UI_Mainwindow::convert_wave_to_edf() { UI_WAV2EDFwindow fino2edf(recent_opendir, recent_savedir); } void UI_Mainwindow::convert_nexfin_to_edf() { UI_NEXFIN2EDFwindow nexfin2edf(recent_opendir, recent_savedir); } void UI_Mainwindow::convert_emsa_to_edf() { UI_EMSA2EDFwindow emsa2edf(recent_opendir, recent_savedir); } void UI_Mainwindow::convert_manscan_to_edf() { UI_MANSCAN2EDFwindow manscan2edf(recent_opendir, recent_savedir); } void UI_Mainwindow::convert_scpecg_to_edf() { UI_SCPECG2EDFwindow scpecg2edf(recent_opendir, recent_savedir); } void UI_Mainwindow::edfd_converter() { UI_EDFDwindow edfplusd2edfplusc(recent_opendir, recent_savedir); } void UI_Mainwindow::bdf2edf_converter() { UI_BDF2EDFwindow bdf2edfconv(this); } void UI_Mainwindow::biosemi2bdfplus_converter() { UI_BIOSEMI2BDFPLUSwindow biosemi2bdfplusconv(this); } void UI_Mainwindow::reduce_signals() { if(!files_open) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "You have to open the file first."); messagewindow.exec(); return; } UI_ReduceSignalsWindow reduceSignals(this); } void UI_Mainwindow::edit_header() { UI_headerEditorWindow header_edit(this); } void UI_Mainwindow::unisens2edf_converter() { UI_UNISENS2EDFwindow unisens2edfconv(recent_opendir, recent_savedir); } void UI_Mainwindow::BI98002edf_converter() { UI_BI98002EDFwindow BI98002edfconv(recent_opendir, recent_savedir); } void UI_Mainwindow::edit_predefined_montages() { UI_edit_predefined_mtg_window edit_predef_mtgs_app(this); } void UI_Mainwindow::jump_to_dialog() { UI_JumpMenuDialog jumpmenu(this); } void UI_Mainwindow::jump_to_start() { int i; if(viewtime_sync==VIEWTIME_SYNCED_OFFSET) { for(i=0; iviewtime = 0; } } if(viewtime_sync==VIEWTIME_UNSYNCED) { edfheaderlist[sel_viewtime]->viewtime = 0; } if(viewtime_sync==VIEWTIME_SYNCED_ABSOLUT) { edfheaderlist[sel_viewtime]->viewtime = 0; for(i=0; iviewtime = ((edfheaderlist[sel_viewtime]->utc_starttime - edfheaderlist[i]->utc_starttime) * TIME_DIMENSION) + edfheaderlist[sel_viewtime]->starttime_offset - edfheaderlist[i]->starttime_offset; } } } if(viewtime_sync==VIEWTIME_USER_DEF_SYNCED) { for(i=0; iviewtime -= edfheaderlist[sel_viewtime]->viewtime; } } edfheaderlist[sel_viewtime]->viewtime = 0; } setup_viewbuf(); } void UI_Mainwindow::jump_to_end() { int i; long long new_viewtime; new_viewtime = edfheaderlist[sel_viewtime]->datarecords * edfheaderlist[sel_viewtime]->long_data_record_duration - pagetime; if(viewtime_sync==VIEWTIME_SYNCED_OFFSET) { for(i=0; iviewtime = new_viewtime; } } if(viewtime_sync==VIEWTIME_UNSYNCED) { edfheaderlist[sel_viewtime]->viewtime = new_viewtime; } if(viewtime_sync==VIEWTIME_SYNCED_ABSOLUT) { edfheaderlist[sel_viewtime]->viewtime = new_viewtime; for(i=0; iviewtime = edfheaderlist[sel_viewtime]->viewtime + edfheaderlist[sel_viewtime]->starttime_offset - ((edfheaderlist[i]->utc_starttime - edfheaderlist[sel_viewtime]->utc_starttime) * TIME_DIMENSION) - edfheaderlist[i]->starttime_offset; } } } if(viewtime_sync==VIEWTIME_USER_DEF_SYNCED) { for(i=0; iviewtime -= (edfheaderlist[sel_viewtime]->viewtime - new_viewtime); } } edfheaderlist[sel_viewtime]->viewtime = new_viewtime; } setup_viewbuf(); } void UI_Mainwindow::add_new_filter() { UI_FilterDialog filterdialog(this); } // void UI_Mainwindow::add_new_math_func() // { // } // void UI_Mainwindow::remove_all_math_funcs() // { // } void UI_Mainwindow::zoomback() { int i, j; if(!zoomhistory->history_size_tail) { return; } zoomhistory->history_size_front++; zoomhistory->history_size_tail--; for(i=0; iviewtime[zoomhistory->pntr][i] = edfheaderlist[i]->viewtime; } zoomhistory->pagetime[zoomhistory->pntr] = pagetime; for(i=0; ivoltpercm[zoomhistory->pntr][i] = signalcomp[i]->voltpercm; zoomhistory->screen_offset[zoomhistory->pntr][i] = signalcomp[i]->screen_offset; for(j=0; jnum_of_signals; j++) { zoomhistory->sensitivity[zoomhistory->pntr][i][j] = signalcomp[i]->sensitivity[j]; } } zoomhistory->pntr--; if(zoomhistory->pntr<0) zoomhistory->pntr = 63; for(i=0; iviewtime = zoomhistory->viewtime[zoomhistory->pntr][i]; } pagetime = zoomhistory->pagetime[zoomhistory->pntr]; for(i=0; ivoltpercm = zoomhistory->voltpercm[zoomhistory->pntr][i]; signalcomp[i]->screen_offset = zoomhistory->screen_offset[zoomhistory->pntr][i]; for(j=0; jnum_of_signals; j++) { signalcomp[i]->sensitivity[j] = zoomhistory->sensitivity[zoomhistory->pntr][i][j]; } } setup_viewbuf(); } void UI_Mainwindow::forward() { int i, j; if(!zoomhistory->history_size_front) { return; } zoomhistory->history_size_front--; zoomhistory->history_size_tail++; zoomhistory->pntr++; if(zoomhistory->pntr>63) zoomhistory->pntr = 0; for(i=0; iviewtime = zoomhistory->viewtime[zoomhistory->pntr][i]; } pagetime = zoomhistory->pagetime[zoomhistory->pntr]; for(i=0; ivoltpercm = zoomhistory->voltpercm[zoomhistory->pntr][i]; signalcomp[i]->screen_offset = zoomhistory->screen_offset[zoomhistory->pntr][i]; for(j=0; jnum_of_signals; j++) { signalcomp[i]->sensitivity[j] = zoomhistory->sensitivity[zoomhistory->pntr][i][j]; } } setup_viewbuf(); } void UI_Mainwindow::former_page() { int i; if((viewtime_sync==VIEWTIME_SYNCED_OFFSET)||(viewtime_sync==VIEWTIME_SYNCED_ABSOLUT)||(viewtime_sync==VIEWTIME_USER_DEF_SYNCED)) { for(i=0; iviewtime -= pagetime; } } if(viewtime_sync==VIEWTIME_UNSYNCED) { edfheaderlist[sel_viewtime]->viewtime -= pagetime; } setup_viewbuf(); } void UI_Mainwindow::shift_page_left() { int i; if((viewtime_sync==VIEWTIME_SYNCED_OFFSET)||(viewtime_sync==VIEWTIME_SYNCED_ABSOLUT)||(viewtime_sync==VIEWTIME_USER_DEF_SYNCED)) { for(i=0; iviewtime -= (pagetime / 10); } } if(viewtime_sync==VIEWTIME_UNSYNCED) { edfheaderlist[sel_viewtime]->viewtime -= (pagetime / 10); } setup_viewbuf(); } void UI_Mainwindow::shift_page_right() { int i; if((viewtime_sync==VIEWTIME_SYNCED_OFFSET)||(viewtime_sync==VIEWTIME_SYNCED_ABSOLUT)||(viewtime_sync==VIEWTIME_USER_DEF_SYNCED)) { for(i=0; iviewtime += (pagetime / 10); } } if(viewtime_sync==VIEWTIME_UNSYNCED) { edfheaderlist[sel_viewtime]->viewtime += (pagetime / 10); } setup_viewbuf(); } void UI_Mainwindow::next_page() { int i; if((viewtime_sync==VIEWTIME_SYNCED_OFFSET)||(viewtime_sync==VIEWTIME_SYNCED_ABSOLUT)||(viewtime_sync==VIEWTIME_USER_DEF_SYNCED)) { for(i=0; iviewtime += pagetime; } } if(viewtime_sync==VIEWTIME_UNSYNCED) { edfheaderlist[sel_viewtime]->viewtime += pagetime; } setup_viewbuf(); } void UI_Mainwindow::shift_page_up() { int i; for(i=0; iscreen_offset += (height() / 20.0); } maincurve->drawCurve_stage_1(); } void UI_Mainwindow::shift_page_down() { int i; for(i=0; iscreen_offset -= (height() / 20.0); } maincurve->drawCurve_stage_1(); } void UI_Mainwindow::show_annotations() { int i; EDF_annotations annotations; for(i=0; iannots_not_read) { if((edfheaderlist[i]->edfplus) || (edfheaderlist[i]->bdfplus)) { edfheaderlist[i]->annots_not_read = 0; annotations.get_annotations(i, edfheaderlist[i], &annotationlist[i], read_nk_trigger_signal); if(edfheaderlist[i]->annots_not_read) { edfplus_annotation_delete_list(&annotationlist[i]); } else { if(annotations_dock[i] == NULL) { annotations_dock[i] = new UI_Annotationswindow(i, this); addDockWidget(Qt::RightDockWidgetArea, annotations_dock[i]->docklist, Qt::Vertical); } } } } if(annotationlist[i] != NULL) { if(annotations_dock[i] != NULL) { annotations_dock[i]->docklist->show(); } } } } void UI_Mainwindow::annotation_editor() { if(files_open==1) { if(edfheaderlist[0]->annots_not_read) { edfplus_annotation_delete_list(&annotationlist[0]); if(annotations_dock[0] != NULL) { annotations_dock[0]->docklist->close(); delete annotations_dock[0]; annotations_dock[0] = NULL; } edfheaderlist[0]->annots_not_read = 0; EDF_annotations annotations; annotations.get_annotations(0, edfheaderlist[0], &annotationlist[0], read_nk_trigger_signal); if(edfheaderlist[0]->annots_not_read) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Editing annotations is not possible when you abort the scanning of the file."); messagewindow.exec(); return; } } if(annotations_dock[0]==NULL) { annotations_dock[0] = new UI_Annotationswindow(0, this); addDockWidget(Qt::RightDockWidgetArea, annotations_dock[0]->docklist, Qt::Vertical); } annotations_dock[0]->docklist->show(); annotationEditDock->dockedit->show(); } else { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Editing annotations is possible when you have opened one file only."); messagewindow.exec(); } } void UI_Mainwindow::show_spectrum_dock() { UI_SignalChooser signalchooserdialog(this, 1); } void UI_Mainwindow::open_new_file() { FILE *newfile; int i, len, present, position, button_nr=0; char str[2048]; str[0] = 0; struct edfhdrblock *edfhdr=NULL; if(annot_editor_active&&files_open) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "You can not open multiple files when editing annotations.\n" "Close the annotation edit window first."); messagewindow.exec(); cmdlineargument = 0; return; } if((files_open > 0) && (live_stream_active)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "You can not open multiple files while a streaming file is open.\n" "Close the streaming file first."); messagewindow.exec(); return; } if(files_open>=MAXFILES) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There are too many files opened."); messagewindow.exec(); cmdlineargument = 0; return; } if(cmdlineargument == 0) { strcpy(path, QFileDialog::getOpenFileName(this, "Open file", QString::fromLocal8Bit(recent_opendir), "EDF/BDF files (*.edf *.EDF *.bdf *.BDF *.rec *.REC)").toLocal8Bit().data()); if(!strcmp(path, "")) { return; } get_directory_from_path(recent_opendir, path, MAX_PATH_LENGTH); } if((cmdlineargument == 0) || (cmdlineargument == 1)) { montagepath[0] = 0; } present = 0; for(i=0; i0; i--) { strcpy(&recent_file_path[i][0], &recent_file_path[i-1][0]); strcpy(&recent_file_mtg_path[i][0], &recent_file_mtg_path[i-1][0]); } } else { for(i=MAX_RECENTFILES-1; i>0; i--) { strcpy(&recent_file_path[i][0], &recent_file_path[i-1][0]); strcpy(&recent_file_mtg_path[i][0], &recent_file_mtg_path[i-1][0]); } } strcpy(&recent_file_path[0][0], path); strcpy(&recent_file_mtg_path[0][0], montagepath); recent_filesmenu->clear(); for(i=0; iaddAction(QString::fromLocal8Bit(&recent_file_path[i][0])); } present = 0; for(i=0; ifilename, path)) { present = 1; break; } } if(!present) { len = strlen(path); if((strcmp(path + (len - 4), ".edf")) &&(strcmp(path + (len - 4), ".EDF")) &&(strcmp(path + (len - 4), ".rec")) &&(strcmp(path + (len - 4), ".REC")) &&(strcmp(path + (len - 4), ".bdf")) &&(strcmp(path + (len - 4), ".BDF"))) { snprintf(str, 2048, "File has an unknown extension: \"%s\"", path + (len - 4)); QMessageBox messagewindow(QMessageBox::Critical, "Error", QString::fromLocal8Bit(str)); messagewindow.exec(); cmdlineargument = 0; return; } newfile = fopeno(path, "rb"); if(newfile==NULL) { snprintf(str, 2048, "Can not open file for reading:\n\"%s\"\n" "Check if you have the right permissions.", path); QMessageBox messagewindow(QMessageBox::Critical, "Error", QString::fromLocal8Bit(str)); messagewindow.exec(); cmdlineargument = 0; return; } strcpy(recent_opendir, path); if(len) { for(i=len-1; i>=0; i--) { if((path[i] == '/')||(path[i] == '\\')) { break; } } } recent_opendir[i] = 0; EDFfileCheck EDFfilechecker; edfhdr = EDFfilechecker.check_edf_file(newfile, str, live_stream_active); if(edfhdr==NULL) { fclose(newfile); strcat(str, "\n File is not a valid EDF or BDF file."); QMessageBox messagewindow(QMessageBox::Critical, "Error", str); messagewindow.exec(); cmdlineargument = 0; return; } if(edfhdr->discontinuous) { if(edfhdr->edf) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "EDFbrowser can not show EDF+D (discontiguous) files.\n" "Convert this file to EDF+C first. You can find this converter\n" "in the Tools menu (EDF+D to EDF+C converter)."); messagewindow.exec(); } if(edfhdr->bdf) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "EDFbrowser can not show BDF+D (discontiguous) files.\n" "Convert this file to BDF+C first. You can find this converter\n" "in the Tools menu (EDF+D to EDF+C converter)."); messagewindow.exec(); } free(edfhdr->edfparam); free(edfhdr); fclose(newfile); cmdlineargument = 0; return; } strcpy(edfhdr->filename, path); edfhdr->file_hdl = newfile; edfhdr->file_num = files_open; edfheaderlist[files_open] = edfhdr; annotationlist[files_open] = NULL; annotations_dock[files_open] = NULL; if((edfhdr->edfplus || edfhdr->bdfplus) && (!live_stream_active)) { if((edfhdr->datarecords * (long long)edfhdr->recordsize) <= maxfilesize_to_readin_annotations) { EDF_annotations annotations; annotations.get_annotations(files_open, edfhdr, &annotationlist[files_open], read_nk_trigger_signal); if(edfhdr->annots_not_read) { edfplus_annotation_delete_list(&annotationlist[files_open]); } else { annotations_dock[files_open] = new UI_Annotationswindow(files_open, this); addDockWidget(Qt::RightDockWidgetArea, annotations_dock[files_open]->docklist, Qt::Vertical); if(!annotationlist[files_open]) { annotations_dock[files_open]->docklist->hide(); } } } else { edfhdr->annots_not_read = 1; } } if((edfhdr->bdf && (!edfhdr->bdfplus) && read_biosemi_status_signal) && (!live_stream_active)) { if((edfhdr->datarecords * (long long)edfhdr->recordsize) <= maxfilesize_to_readin_annotations) { BDF_triggers bdf_triggers_obj; bdf_triggers_obj.get_triggers(edfhdr, &annotationlist[files_open]); annotations_dock[files_open] = new UI_Annotationswindow(files_open, this); addDockWidget(Qt::RightDockWidgetArea, annotations_dock[files_open]->docklist, Qt::Vertical); if(!annotationlist[files_open]) { annotations_dock[files_open]->docklist->hide(); } } } if(!files_open) { edfheaderlist[0]->viewtime = 0; setMainwindowTitle(edfhdr); } else { if(viewtime_sync==VIEWTIME_SYNCED_OFFSET) { edfheaderlist[files_open]->viewtime = edfheaderlist[sel_viewtime]->viewtime; } if(viewtime_sync==VIEWTIME_UNSYNCED) { edfheaderlist[files_open]->viewtime = 0; } if(viewtime_sync==VIEWTIME_SYNCED_ABSOLUT) { edfheaderlist[files_open]->viewtime = edfheaderlist[sel_viewtime]->viewtime + edfheaderlist[sel_viewtime]->starttime_offset - edfheaderlist[files_open]->starttime_offset - ((edfheaderlist[files_open]->utc_starttime - edfheaderlist[sel_viewtime]->utc_starttime) * TIME_DIMENSION); } if(viewtime_sync==VIEWTIME_USER_DEF_SYNCED) { edfheaderlist[files_open]->viewtime = 0; } } sel_viewtime_act[files_open] = new QAction(QString::fromLocal8Bit(edfhdr->filename), this); sel_viewtime_act[files_open]->setCheckable(TRUE); if(!files_open) { sel_viewtime_act[files_open]->setChecked(TRUE); } sel_viewtime_act_group->addAction(sel_viewtime_act[files_open]); timemenu->addAction(sel_viewtime_act[files_open]); files_open++; } if((montagepath[0]!=0)&&(cmdlineargument==2)) { UI_LoadMontagewindow load_mtg(this, montagepath); strcpy(&recent_file_mtg_path[0][0], montagepath); } else { if((recent_file_mtg_path[0][0] != 0) && (files_open == 1) && auto_reload_mtg) { QMessageBox messagewindow; messagewindow.setText("Load last used montage?"); messagewindow.setInformativeText(QString::fromLocal8Bit(&recent_file_mtg_path[0][0])); messagewindow.setIcon(QMessageBox::Question); messagewindow.setStandardButtons(QMessageBox::Yes | QMessageBox::No); messagewindow.setDefaultButton(QMessageBox::Yes); button_nr = messagewindow.exec(); if(button_nr == QMessageBox::No) { recent_file_mtg_path[0][0] = 0; UI_Signalswindow signalwindow(this); } else { UI_LoadMontagewindow load_mtg(this, &recent_file_mtg_path[0][0]); if(recent_file_mtg_path[0][0] == 0) { UI_Signalswindow signalwindow(this); } } } else { UI_Signalswindow signalwindow(this); } } cmdlineargument = 0; } void UI_Mainwindow::remove_recent_file_mtg_path(const char *mtg_path) { int i; for(i=0; iedfplus || edfhdr->bdfplus) { snprintf(str, 256, PROGRAM_NAME " subject %s birthdate %s startdate %s", edfhdr->plus_patient_name, edfhdr->plus_birthdate, edfhdr->plus_startdate); } else { utc_to_date_time(edfhdr->utc_starttime, &date_time); date_time.month_str[0] += 32; date_time.month_str[1] += 32; date_time.month_str[2] += 32; snprintf(str, 256, PROGRAM_NAME " %s startdate %i %s %i", edfhdr->patient, date_time.day, date_time.month_str, date_time.year); len = strlen(str); for(i=0; ifilename, MAX_PATH_LENGTH); strcat(str, " - " PROGRAM_NAME); } if(mainwindow_title_type == 2) { strcpy(str, edfhdr->filename); strcat(str, " - " PROGRAM_NAME); } setWindowTitle(str); } void UI_Mainwindow::signalproperties_dialog() { UI_SignalChooser signalchooserdialog(this, 0); } void UI_Mainwindow::filterproperties_dialog() { UI_SignalChooser signalchooserdialog(this, 2); } void UI_Mainwindow::add_signals_dialog() { UI_Signalswindow signalwindow(this); } void UI_Mainwindow::show_splashscreen() { splash = new QSplashScreen(this, *pixmap, Qt::WindowStaysOnTopHint); splash->show(); } void UI_Mainwindow::show_file_info() { UI_EDFhdrwindow showhdr(this); } void UI_Mainwindow::remove_all_filters() { int i, j, update_scr=0; for(i=0; ifilter_cnt; j++) { free(signalcomp[i]->filter[j]); update_scr = 1; } signalcomp[i]->filter_cnt = 0; for(j=0; jfidfilter_cnt; j++) { free(signalcomp[i]->fidfilter[j]); fid_run_free(signalcomp[i]->fid_run[j]); fid_run_freebuf(signalcomp[i]->fidbuf[j]); fid_run_freebuf(signalcomp[i]->fidbuf2[j]); update_scr = 1; } signalcomp[i]->fidfilter_cnt = 0; for(j=0; jravg_filter_cnt; j++) { free_ravg_filter(signalcomp[i]->ravg_filter[j]); update_scr = 1; } signalcomp[i]->ravg_filter_cnt = 0; if(signalcomp[i]->ecg_filter != NULL) { free_ecg_filter(signalcomp[i]->ecg_filter); signalcomp[i]->ecg_filter = NULL; strcpy(signalcomp[i]->signallabel, signalcomp[i]->signallabel_bu); signalcomp[i]->signallabellen = signalcomp[i]->signallabellen_bu; strcpy(signalcomp[i]->physdimension, signalcomp[i]->physdimension_bu); } if(signalcomp[i]->zratio_filter != NULL) { free_zratio_filter(signalcomp[i]->zratio_filter); signalcomp[i]->zratio_filter = NULL; strcpy(signalcomp[i]->signallabel, signalcomp[i]->signallabel_bu); signalcomp[i]->signallabellen = signalcomp[i]->signallabellen_bu; strcpy(signalcomp[i]->physdimension, signalcomp[i]->physdimension_bu); } } if(update_scr) { setup_viewbuf(); } } void UI_Mainwindow::remove_all_signals() { int i; spectrumdock->clear(); spectrumdock->dock->hide(); for(i=0; icrosshair_1.active = 0; maincurve->crosshair_2.active = 0; maincurve->crosshair_1.moving = 0; maincurve->crosshair_2.moving = 0; remove_all_filters(); for(i=0; isetEnabled(FALSE); positionslider->blockSignals(TRUE); setup_viewbuf(); } void UI_Mainwindow::close_all_files() { int i, j, k, button_nr=0; live_stream_active = 0; live_stream_timer->stop(); toolsmenu->setEnabled(TRUE); timemenu->setEnabled(TRUE); windowmenu->setEnabled(TRUE); former_page_Act->setEnabled(TRUE); shift_page_left_Act->setEnabled(TRUE); shift_page_right_Act->setEnabled(TRUE); next_page_Act->setEnabled(TRUE); shift_page_up_Act->setEnabled(TRUE); shift_page_down_Act->setEnabled(TRUE); printmenu->setEnabled(TRUE); recent_filesmenu->setEnabled(TRUE); if(annotations_edited) { QMessageBox messagewindow; messagewindow.setText("There are unsaved annotations,\n are you sure you want to close this file?"); messagewindow.setIcon(QMessageBox::Question); messagewindow.setStandardButtons(QMessageBox::Cancel | QMessageBox::Close); messagewindow.setDefaultButton(QMessageBox::Cancel); button_nr = messagewindow.exec(); } if(button_nr == QMessageBox::Cancel) { return; } annotations_edited = 0; #ifdef BK_MRS_project // temporary code for private use in a certain project // do not use this code, it will be removed in future if(bk_mrs_project_file != NULL) { fclose(bk_mrs_project_file); bk_mrs_project_file = NULL; } #endif remove_all_signals(); while(files_open) { files_open--; if(edfheaderlist[files_open]->file_hdl != NULL) { fclose(edfheaderlist[files_open]->file_hdl); } free(edfheaderlist[files_open]->edfparam); free(edfheaderlist[files_open]); edfplus_annotation_delete_list(&annotationlist[files_open]); if(annotations_dock[files_open] != NULL) { annotations_dock[files_open]->docklist->close(); delete annotations_dock[files_open]; annotations_dock[files_open] = NULL; } delete sel_viewtime_act[files_open]; } edfplus_annotation_delete_list(&annotationlist_backup); sel_viewtime = 0; pagetime = 10 * TIME_DIMENSION; timescale_doubler = 10; amplitude_doubler = 10; for(i=0; i<64; i++) { zoomhistory->pntr = 0; zoomhistory->pagetime[i] = 10 * TIME_DIMENSION; for(j=0; jviewtime[i][j] = 0; } for(j=0; jvoltpercm[i][j] = 70; zoomhistory->screen_offset[i][j] = 0.0; for(k=0; ksensitivity[i][j][k] = 0.0475; } } } annotationEditDock->dockedit->hide(); save_act->setEnabled(FALSE); annotations_edited = 0; setWindowTitle(PROGRAM_NAME); if(!exit_in_progress) { maincurve->update(); } } void UI_Mainwindow::show_about_dialog() { UI_Aboutwindow aboutwindow(this); } void UI_Mainwindow::page_3cmsec() { double mm; if(auto_dpi) { mm = maincurve->widthMM(); pagetime = mm * 333333.3333; } else { pagetime = (long long)((((double)maincurve->width()) / (1.0 / x_pixelsizefactor) / 3.0) * TIME_DIMENSION); } setup_viewbuf(); } void UI_Mainwindow::set_page_div2() { int i; long long l_tmp, trshld=100LL; if((viewtime_sync==VIEWTIME_SYNCED_OFFSET)||(viewtime_sync==VIEWTIME_SYNCED_ABSOLUT)||(viewtime_sync==VIEWTIME_USER_DEF_SYNCED)) { for(i=0; iviewtime += (pagetime * 0.3); } else { edfheaderlist[i]->viewtime += (pagetime / 4); } l_tmp = edfheaderlist[i]->viewtime % TIME_DIMENSION; if(l_tmp < trshld) { edfheaderlist[i]->viewtime -= l_tmp; } if(l_tmp > (TIME_DIMENSION - trshld)) { edfheaderlist[i]->viewtime += (TIME_DIMENSION - l_tmp); } } } if(viewtime_sync==VIEWTIME_UNSYNCED) { if(timescale_doubler == 50) { edfheaderlist[sel_viewtime]->viewtime += (pagetime * 0.3); } else { edfheaderlist[sel_viewtime]->viewtime += (pagetime / 4); } l_tmp = edfheaderlist[sel_viewtime]->viewtime % TIME_DIMENSION; if(l_tmp < trshld) { edfheaderlist[sel_viewtime]->viewtime -= l_tmp; } if(l_tmp > (TIME_DIMENSION - trshld)) { edfheaderlist[sel_viewtime]->viewtime += (TIME_DIMENSION - l_tmp); } } if(timescale_doubler == 10) { timescale_doubler = 50; pagetime /= 2; } else { if(timescale_doubler == 50) { timescale_doubler = 20; pagetime /= 2.5; } else { timescale_doubler = 10; pagetime /= 2; } } setup_viewbuf(); } void UI_Mainwindow::set_page_mult2() { int i; long long l_tmp, trshld=100LL; if((viewtime_sync==VIEWTIME_SYNCED_OFFSET)||(viewtime_sync==VIEWTIME_SYNCED_ABSOLUT)||(viewtime_sync==VIEWTIME_USER_DEF_SYNCED)) { for(i=0; iviewtime -= (pagetime * 0.75); } else { edfheaderlist[i]->viewtime -= (pagetime / 2); } l_tmp = edfheaderlist[i]->viewtime % TIME_DIMENSION; if(l_tmp < trshld) { edfheaderlist[i]->viewtime -= l_tmp; } if(l_tmp > (TIME_DIMENSION - trshld)) { edfheaderlist[i]->viewtime += (TIME_DIMENSION - l_tmp); } } } if(viewtime_sync==VIEWTIME_UNSYNCED) { if(timescale_doubler == 20) { edfheaderlist[sel_viewtime]->viewtime -= (pagetime * 0.75); } else { edfheaderlist[sel_viewtime]->viewtime -= (pagetime / 2); } } if(timescale_doubler == 10) { timescale_doubler = 20; pagetime *= 2; } else { if(timescale_doubler == 20) { timescale_doubler = 50; pagetime *= 2.5; } else { timescale_doubler = 10; pagetime *= 2; } } setup_viewbuf(); } void UI_Mainwindow::set_display_time(QAction *action) { if(action==page_10m) { pagetime = TIME_DIMENSION / 100; timescale_doubler = 10; } if(action==page_20m) { pagetime = TIME_DIMENSION / 50; timescale_doubler = 20; } if(action==page_50m) { pagetime = TIME_DIMENSION / 20; timescale_doubler = 50; } if(action==page_100m) { pagetime = TIME_DIMENSION / 10; timescale_doubler = 10; } if(action==page_200m) { pagetime = TIME_DIMENSION / 5; timescale_doubler = 20; } if(action==page_500m) { pagetime = TIME_DIMENSION / 2; timescale_doubler = 50; } if(action==page_1) { pagetime = TIME_DIMENSION; timescale_doubler = 10; } if(action==page_2) { pagetime = TIME_DIMENSION * 2; timescale_doubler = 20; } if(action==page_5) { pagetime = TIME_DIMENSION * 5; timescale_doubler = 50; } if(action==page_10) { pagetime = TIME_DIMENSION * 10; timescale_doubler = 10; } if(action==page_15) pagetime = TIME_DIMENSION * 15; if(action==page_20) { pagetime = TIME_DIMENSION * 20; timescale_doubler = 20; } if(action==page_30) pagetime = TIME_DIMENSION * 30; if(action==page_60) pagetime = TIME_DIMENSION * 60; if(action==page_300) pagetime = TIME_DIMENSION * 300; if(action==page_1200) pagetime = TIME_DIMENSION * 1200; if(action==page_3600) pagetime = TIME_DIMENSION * 3600; setup_viewbuf(); } void UI_Mainwindow::set_user_defined_display_time() { UI_Userdefined_timepage_Dialog set_displaytime_dialog(this); } void UI_Mainwindow::set_display_time_whole_rec() { int i; if(!files_open) return; if(viewtime_sync==VIEWTIME_SYNCED_OFFSET) { for(i=0; iviewtime = 0; } } if(viewtime_sync==VIEWTIME_UNSYNCED) { edfheaderlist[sel_viewtime]->viewtime = 0; } if(viewtime_sync==VIEWTIME_SYNCED_ABSOLUT) { edfheaderlist[sel_viewtime]->viewtime = 0; for(i=0; iviewtime = ((edfheaderlist[sel_viewtime]->utc_starttime - edfheaderlist[i]->utc_starttime) * TIME_DIMENSION) + edfheaderlist[sel_viewtime]->starttime_offset - - edfheaderlist[i]->starttime_offset; } } } if(viewtime_sync==VIEWTIME_USER_DEF_SYNCED) { for(i=0; iviewtime -= edfheaderlist[sel_viewtime]->viewtime; } } edfheaderlist[sel_viewtime]->viewtime = 0; } pagetime = edfheaderlist[sel_viewtime]->datarecords * edfheaderlist[sel_viewtime]->long_data_record_duration; setup_viewbuf(); } void UI_Mainwindow::fit_signals_to_pane() { int i, j, pane_size; if(!signalcomps) return; pane_size = maincurve->height() / (signalcomps + 1); for(i=0; inum_of_signals; j++) { if(signalcomp[i]->max_dig_value!=signalcomp[i]->min_dig_value) { signalcomp[i]->sensitivity[j] = (double)pane_size / (double)(signalcomp[i]->max_dig_value - signalcomp[i]->min_dig_value); } else { signalcomp[i]->sensitivity[j] = pane_size; } } signalcomp[i]->voltpercm = signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].bitvalue / (signalcomp[i]->sensitivity[0] * pixelsizefactor); signalcomp[i]->screen_offset = ((signalcomp[i]->max_dig_value + signalcomp[i]->min_dig_value) / 2.0) * signalcomp[i]->sensitivity[0]; } maincurve->drawCurve_stage_1(); } void UI_Mainwindow::fit_signals_dc_offset() { int i; if(!signalcomps) return; for(i=0; iscreen_offset = ((signalcomp[i]->max_dig_value + signalcomp[i]->min_dig_value) / 2.0) * signalcomp[i]->sensitivity[0]; } maincurve->drawCurve_stage_1(); } void UI_Mainwindow::set_amplitude(QAction *action) { int i, j; double value=100.0, original_value, value2=100.0; if(action==amp_00001) { value = 0.0001; amplitude_doubler = 10; } if(action==amp_00002) { value = 0.0002; amplitude_doubler = 20; } if(action==amp_00005) { value = 0.0005; amplitude_doubler = 50; } if(action==amp_0001) { value = 0.001; amplitude_doubler = 10; } if(action==amp_0002) { value = 0.002; amplitude_doubler = 20; } if(action==amp_0005) { value = 0.005; amplitude_doubler = 50; } if(action==amp_001) { value = 0.01; amplitude_doubler = 10; } if(action==amp_002) { value = 0.02; amplitude_doubler = 20; } if(action==amp_005) { value = 0.05; amplitude_doubler = 50; } if(action==amp_01) { value = 0.1; amplitude_doubler = 10; } if(action==amp_02) { value = 0.2; amplitude_doubler = 20; } if(action==amp_05) { value = 0.5; amplitude_doubler = 50; } if(action==amp_1) { value = 1.0; amplitude_doubler = 10; } if(action==amp_2) { value = 2.0; amplitude_doubler = 20; } if(action==amp_5) { value = 5.0; amplitude_doubler = 50; } if(action==amp_10) { value = 10.0; amplitude_doubler = 10; } if(action==amp_20) { value = 20.0; amplitude_doubler = 20; } if(action==amp_50) { value = 50.0; amplitude_doubler = 50; } if(action==amp_100) { value = 100.0; amplitude_doubler = 10; } if(action==amp_200) { value = 200.0; amplitude_doubler = 20; } if(action==amp_500) { value = 500.0; amplitude_doubler = 50; } if(action==amp_1000) { value = 1000.0; amplitude_doubler = 10; } if(action==amp_2000) { value = 2000.0; amplitude_doubler = 20; } if(action==amp_5000) { value = 5000.0; amplitude_doubler = 50; } if(action==amp_10000) { value = 10000.0; amplitude_doubler = 10; } if(action==amp_20000) { value = 20000.0; amplitude_doubler = 20; } if(action==amp_50000) { value = 50000.0; amplitude_doubler = 50; } for(i=0; iedfhdr->edfparam[signalcomp[i]->edfsignal[0]].bitvalue < 0.0) { value2 *= -1.0; } for(j=0; jnum_of_signals; j++) { signalcomp[i]->sensitivity[j] = (signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[j]].bitvalue / value2) / pixelsizefactor; } original_value = signalcomp[i]->voltpercm; signalcomp[i]->voltpercm = value2; signalcomp[i]->screen_offset *= (original_value / value2); } maincurve->drawCurve_stage_1(); } void UI_Mainwindow::set_amplitude_mult2() { int i, j; for(i=0; ivoltpercm < 0) { if(signalcomp[i]->voltpercm < -5000000.0) { return; } } else { if(signalcomp[i]->voltpercm > 5000000.0) { return; } } } for(i=0; ivoltpercm *= 2; signalcomp[i]->screen_offset /= 2; } else { signalcomp[i]->voltpercm *= 2.5; signalcomp[i]->screen_offset /= 2.5; } for(j=0; jnum_of_signals; j++) { signalcomp[i]->sensitivity[j] = (signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[j]].bitvalue / signalcomp[i]->voltpercm) / pixelsizefactor; } } if(amplitude_doubler == 10) { amplitude_doubler = 20; } else { if(amplitude_doubler == 20) { amplitude_doubler = 50; } else { amplitude_doubler = 10; } } maincurve->drawCurve_stage_1(); } void UI_Mainwindow::set_amplitude_div2() { int i, j; for(i=0; ivoltpercm < 0) { if(signalcomp[i]->voltpercm > -0.000001) { return; } } else { if(signalcomp[i]->voltpercm < 0.000001) { return; } } } for(i=0; ivoltpercm /= 2; signalcomp[i]->screen_offset *= 2; } else { signalcomp[i]->voltpercm /= 2.5; signalcomp[i]->screen_offset *= 2.5; } for(j=0; jnum_of_signals; j++) { signalcomp[i]->sensitivity[j] = (signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[j]].bitvalue / signalcomp[i]->voltpercm) / pixelsizefactor; } } if(amplitude_doubler == 10) { amplitude_doubler = 50; } else { if(amplitude_doubler == 50) { amplitude_doubler = 20; } else { amplitude_doubler = 10; } } maincurve->drawCurve_stage_1(); } void UI_Mainwindow::load_predefined_mtg(QAction *action) { int i; if(!files_open) { return; } for(i=0; i < MAXPREDEFINEDMONTAGES; i++) { if(action==load_predefined_mtg_act[i]) { if(predefined_mtg_path[i][0] != 0) { strcpy(montagepath, &predefined_mtg_path[i][0]); UI_LoadMontagewindow load_mtg(this, montagepath); return; } } } } void UI_Mainwindow::setup_viewbuf() { int i, j, k, s, temp=0, skip, totalsize, hasprefilter=0, readsize=0, dif; double pre_time=0.0, d_temp, dig_value; long long l_temp, datarecords; union { unsigned int one; signed int one_signed; unsigned short two[2]; signed short two_signed[2]; unsigned char four[4]; } var; struct date_time_struct date_time_str; for(i=0; iprefiltertime = 0; for(i=0; ifilter_cnt) { hasprefilter = 1; for(k=0; kfilter_cnt; k++) { if(pre_time < (1.0 / signalcomp[i]->filter[k]->cutoff_frequency)) { pre_time = (1.0 / signalcomp[i]->filter[k]->cutoff_frequency); } } } if(signalcomp[i]->ravg_filter_cnt) { hasprefilter = 1; for(k=0; kravg_filter_cnt; k++) { if(pre_time < ((double)(signalcomp[i]->ravg_filter[k]->size + 3) / ((double)signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].smp_per_record / signalcomp[i]->edfhdr->data_record_duration))) { pre_time = (double)(signalcomp[i]->ravg_filter[k]->size + 3) / ((double)signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].smp_per_record / signalcomp[i]->edfhdr->data_record_duration); } } } if(signalcomp[i]->ecg_filter != NULL) { hasprefilter = 1; if(pre_time < 10.0) { pre_time = 10.0; } } if(signalcomp[i]->zratio_filter != NULL) { hasprefilter = 1; if(pre_time < 4.0) { pre_time = 4.0; } } if(signalcomp[i]->fidfilter_cnt) { hasprefilter = 1; for(k=0; kfidfilter_cnt; k++) { if(pre_time < ((2.0 * signalcomp[i]->fidfilter_order[k]) / signalcomp[i]->fidfilter_freq[k])) { pre_time = (2.0 * signalcomp[i]->fidfilter_order[k]) / signalcomp[i]->fidfilter_freq[k]; } } } } if(hasprefilter) { for(i=0; ifilter_cnt) || (signalcomp[i]->ravg_filter_cnt) || (signalcomp[i]->fidfilter_cnt) || (signalcomp[i]->ecg_filter != NULL) || (signalcomp[i]->zratio_filter != NULL)) { signalcomp[i]->edfhdr->prefiltertime = (long long)(pre_time * ((double)TIME_DIMENSION)); if(signalcomp[i]->edfhdr->prefiltertime>signalcomp[i]->edfhdr->viewtime) { signalcomp[i]->edfhdr->prefiltertime = signalcomp[i]->edfhdr->viewtime; if(signalcomp[i]->edfhdr->prefiltertime<0) signalcomp[i]->edfhdr->prefiltertime = 0; } } } totalsize = 0; for(i=0; iedfhdr->prefiltertime) signalcomp[i]->records_in_viewbuf = (signalcomp[i]->edfhdr->viewtime / signalcomp[i]->edfhdr->long_data_record_duration) - ((signalcomp[i]->edfhdr->viewtime - signalcomp[i]->edfhdr->prefiltertime) / signalcomp[i]->edfhdr->long_data_record_duration) + 1; else signalcomp[i]->records_in_viewbuf = 0; signalcomp[i]->viewbufsize = signalcomp[i]->records_in_viewbuf * signalcomp[i]->edfhdr->recordsize; if(signalcomp[i]->edfhdr->prefiltertime) { signalcomp[i]->samples_in_prefilterbuf = (signalcomp[i]->records_in_viewbuf - 1) * signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].smp_per_record; signalcomp[i]->samples_in_prefilterbuf += (int)(((double)(signalcomp[i]->edfhdr->viewtime % signalcomp[i]->edfhdr->long_data_record_duration) / (double)signalcomp[i]->edfhdr->long_data_record_duration) * (double)signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].smp_per_record); } else { signalcomp[i]->samples_in_prefilterbuf = 0; } if(!i) { signalcomp[i]->viewbufoffset = 0; totalsize = signalcomp[i]->viewbufsize; } else { skip = 0; for(j=0; jedfhdr->file_hdl==signalcomp[j]->edfhdr->file_hdl) { skip = 1; signalcomp[i]->viewbufoffset = signalcomp[j]->viewbufoffset; signalcomp[i]->records_in_viewbuf = signalcomp[j]->records_in_viewbuf; signalcomp[i]->viewbufsize = signalcomp[j]->viewbufsize; break; } } if(!skip) { signalcomp[i]->viewbufoffset = signalcomp[i-1]->viewbufoffset + signalcomp[i-1]->viewbufsize; totalsize += signalcomp[i]->viewbufsize; } } } if(viewbuf!=NULL) { free(viewbuf); viewbuf = NULL; } viewbuf = (char *)malloc(totalsize); if(viewbuf==NULL) { live_stream_active = 0; QMessageBox messagewindow(QMessageBox::Critical, "Error", "Internal error: Memory allocation error:\n\"prefilterbuf\""); messagewindow.exec(); remove_all_signals(); return; } for(i=0; iedfhdr->viewtime - signalcomp[i]->edfhdr->prefiltertime) / signalcomp[i]->edfhdr->long_data_record_duration; signalcomp[i]->prefilter_starttime = datarecords * signalcomp[i]->edfhdr->long_data_record_duration; if((signalcomp[i]->viewbufsize>0)&&(datarecordsedfhdr->datarecords)) { fseeko(signalcomp[i]->edfhdr->file_hdl, (long long)(signalcomp[i]->edfhdr->hdrsize + (datarecords * signalcomp[i]->edfhdr->recordsize)), SEEK_SET); if(signalcomp[i]->viewbufsize>((signalcomp[i]->edfhdr->datarecords - datarecords) * signalcomp[i]->edfhdr->recordsize)) { signalcomp[i]->viewbufsize = (signalcomp[i]->edfhdr->datarecords - datarecords) * signalcomp[i]->edfhdr->recordsize; } if(fread(viewbuf + signalcomp[i]->viewbufoffset, signalcomp[i]->viewbufsize, 1, signalcomp[i]->edfhdr->file_hdl)!=1) { live_stream_active = 0; QMessageBox messagewindow(QMessageBox::Critical, "Error", "A read error occurred. 2"); messagewindow.exec(); remove_all_signals(); return; } } } else { skip = 0; for(j=0; jedfhdr->file_hdl==signalcomp[j]->edfhdr->file_hdl) { skip = 1; break; } } if(!skip) { datarecords = (signalcomp[i]->edfhdr->viewtime - signalcomp[i]->edfhdr->prefiltertime) / signalcomp[i]->edfhdr->long_data_record_duration; signalcomp[i]->prefilter_starttime = datarecords * signalcomp[i]->edfhdr->long_data_record_duration; if((signalcomp[i]->viewbufsize>0)&&(datarecordsedfhdr->datarecords)) { fseeko(signalcomp[i]->edfhdr->file_hdl, (long long)(signalcomp[i]->edfhdr->hdrsize + (datarecords * signalcomp[i]->edfhdr->recordsize)), SEEK_SET); if(signalcomp[i]->viewbufsize>((signalcomp[i]->edfhdr->datarecords - datarecords) * signalcomp[i]->edfhdr->recordsize)) { signalcomp[i]->viewbufsize = (signalcomp[i]->edfhdr->datarecords - datarecords) * signalcomp[i]->edfhdr->recordsize; } if(fread(viewbuf + signalcomp[i]->viewbufoffset, signalcomp[i]->viewbufsize, 1, signalcomp[i]->edfhdr->file_hdl)!=1) { live_stream_active = 0; QMessageBox messagewindow(QMessageBox::Critical, "Error", "A read error occurred. 3"); messagewindow.exec(); remove_all_signals(); return; } } } } } for(i=0; izratio_filter != NULL) { l_temp = signalcomp[i]->prefilter_starttime % (TIME_DIMENSION * 2LL); // necessary for the Z-ratio filter if(l_temp != 0L) { temp = (TIME_DIMENSION * 2LL) - l_temp; l_temp = temp; signalcomp[i]->prefilter_reset_sample = (l_temp / signalcomp[i]->edfhdr->long_data_record_duration) * signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].smp_per_record; signalcomp[i]->prefilter_reset_sample += (int)(((double)(l_temp % signalcomp[i]->edfhdr->long_data_record_duration) / (double)signalcomp[i]->edfhdr->long_data_record_duration) * (double)signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].smp_per_record); } else { signalcomp[i]->prefilter_reset_sample = 0; } // printf("records_in_viewbuf is %lli\n" // "samples_in_prefilterbuf is %i\n" // "l_temp is %lli\n" // "temp is %i\n" // "prefilter_reset_sample is %i\n\n", // signalcomp[i]->records_in_viewbuf, // signalcomp[i]->samples_in_prefilterbuf, // l_temp, // temp, // signalcomp[i]->prefilter_reset_sample); } } for(i=0; ifilter_cnt) && (!signalcomp[i]->ravg_filter_cnt) && (!signalcomp[i]->fidfilter_cnt) && (signalcomp[i]->ecg_filter == NULL) && (signalcomp[i]->zratio_filter == NULL)) continue; for(s=0; ssamples_in_prefilterbuf; s++) { dig_value = 0.0; for(k=0; knum_of_signals; k++) { if(signalcomp[i]->edfhdr->bdf) { var.two[0] = *((unsigned short *)( viewbuf + signalcomp[i]->viewbufoffset + (signalcomp[i]->edfhdr->recordsize * (s / signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[k]].smp_per_record)) + signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[k]].buf_offset + ((s % signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[k]].smp_per_record) * 3))); var.four[2] = *((unsigned char *)( viewbuf + signalcomp[i]->viewbufoffset + (signalcomp[i]->edfhdr->recordsize * (s / signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[k]].smp_per_record)) + signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[k]].buf_offset + ((s % signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[k]].smp_per_record) * 3) + 2)); if(var.four[2]&0x80) { var.four[3] = 0xff; } else { var.four[3] = 0x00; } temp = var.one_signed; } if(signalcomp[i]->edfhdr->edf) { temp = *(((short *)( viewbuf + signalcomp[i]->viewbufoffset + (signalcomp[i]->edfhdr->recordsize * (s / signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[k]].smp_per_record)) + signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[k]].buf_offset)) + (s % signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[k]].smp_per_record)); } temp += signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[k]].offset; temp *= signalcomp[i]->factor[k]; dig_value += temp; } for(j=0; jfilter_cnt; j++) { dig_value = first_order_filter(dig_value, signalcomp[i]->filter[j]); } for(j=0; jravg_filter_cnt; j++) { dig_value = run_ravg_filter(dig_value, signalcomp[i]->ravg_filter[j]); } for(j=0; jfidfilter_cnt; j++) { dig_value = signalcomp[i]->fidfuncp[j](signalcomp[i]->fidbuf[j], dig_value); } if(signalcomp[i]->ecg_filter != NULL) { if(s == 0) { reset_ecg_filter(signalcomp[i]->ecg_filter); } dig_value = run_ecg_filter(dig_value, signalcomp[i]->ecg_filter); } if(signalcomp[i]->zratio_filter != NULL) { if(s == signalcomp[i]->prefilter_reset_sample) { reset_zratio_filter(signalcomp[i]->zratio_filter); } dig_value = run_zratio_filter(dig_value, signalcomp[i]->zratio_filter); } } } for(i=0; isamples_in_prefilterbuf > 0) { for(j=0; jfilter_cnt; j++) { signalcomp[i]->filterpreset_a[j] = signalcomp[i]->filter[j]->old_input; signalcomp[i]->filterpreset_b[j] = signalcomp[i]->filter[j]->old_output; } for(j=0; jravg_filter_cnt; j++) { ravg_filter_save_buf(signalcomp[i]->ravg_filter[j]); } for(j=0; jfidfilter_cnt; j++) { memcpy(signalcomp[i]->fidbuf2[j], signalcomp[i]->fidbuf[j], fid_run_bufsize(signalcomp[i]->fid_run[j])); } if(signalcomp[i]->ecg_filter != NULL) { ecg_filter_save_buf(signalcomp[i]->ecg_filter); } if(signalcomp[i]->zratio_filter != NULL) { zratio_filter_save_buf(signalcomp[i]->zratio_filter); } } } } totalsize = 0; for(i=0; iedfhdr->viewtime>=0) signalcomp[i]->records_in_viewbuf = ((pagetime + (signalcomp[i]->edfhdr->viewtime % signalcomp[i]->edfhdr->long_data_record_duration)) / signalcomp[i]->edfhdr->long_data_record_duration) + 1; else signalcomp[i]->records_in_viewbuf = ((pagetime + ((-(signalcomp[i]->edfhdr->viewtime)) % signalcomp[i]->edfhdr->long_data_record_duration)) / signalcomp[i]->edfhdr->long_data_record_duration) + 1; signalcomp[i]->viewbufsize = signalcomp[i]->records_in_viewbuf * signalcomp[i]->edfhdr->recordsize; signalcomp[i]->samples_on_screen = (int)(((double)pagetime / (double)signalcomp[i]->edfhdr->long_data_record_duration) * (double)signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].smp_per_record); if(signalcomp[i]->edfhdr->viewtime<0) { d_temp = (((double)(-(signalcomp[i]->edfhdr->viewtime))) / (double)signalcomp[i]->edfhdr->long_data_record_duration) * (double)signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].smp_per_record; if(d_temp>2147483648.0) { signalcomp[i]->sample_start = 2147483647LL; } else { signalcomp[i]->sample_start = (int)d_temp; } } else { signalcomp[i]->sample_start = 0; } if(signalcomp[i]->edfhdr->viewtime>=0) { signalcomp[i]->sample_timeoffset_part = ((double)(signalcomp[i]->edfhdr->viewtime % signalcomp[i]->edfhdr->long_data_record_duration) / (double)signalcomp[i]->edfhdr->long_data_record_duration) * (double)signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].smp_per_record; signalcomp[i]->sample_timeoffset = (int)(signalcomp[i]->sample_timeoffset_part); signalcomp[i]->sample_timeoffset_part -= signalcomp[i]->sample_timeoffset; } else { signalcomp[i]->sample_timeoffset_part = 0.0; signalcomp[i]->sample_timeoffset = 0; } if(!i) { signalcomp[i]->viewbufoffset = 0; totalsize = signalcomp[i]->viewbufsize; } else { skip = 0; for(j=0; jedfhdr->file_hdl==signalcomp[j]->edfhdr->file_hdl) { skip = 1; signalcomp[i]->viewbufoffset = signalcomp[j]->viewbufoffset; signalcomp[i]->records_in_viewbuf = signalcomp[j]->records_in_viewbuf; signalcomp[i]->viewbufsize = signalcomp[j]->viewbufsize; break; } } if(!skip) { signalcomp[i]->viewbufoffset = signalcomp[i-1]->viewbufoffset + signalcomp[i-1]->viewbufsize; totalsize += signalcomp[i]->viewbufsize; } } } if(viewbuf!=NULL) { free(viewbuf); viewbuf = NULL; } if(totalsize) { viewbuf = (char *)malloc(totalsize); if(viewbuf==NULL) { live_stream_active = 0; QMessageBox messagewindow(QMessageBox::Critical, "Error", "The system was not able to provide enough resources (memory) to perform the requested action.\n" "Decrease the timescale and try again."); messagewindow.exec(); remove_all_signals(); return; } } for(i=0; iedfhdr->viewtime>=0) { datarecords = signalcomp[i]->edfhdr->viewtime / signalcomp[i]->edfhdr->long_data_record_duration; } else { datarecords = 0; } dif = signalcomp[i]->edfhdr->datarecords - datarecords; if(dif<=0) { memset(viewbuf + signalcomp[i]->viewbufoffset, 0, signalcomp[i]->records_in_viewbuf * signalcomp[i]->edfhdr->recordsize); signalcomp[i]->sample_stop = 0; } else { if(difrecords_in_viewbuf) { readsize = dif * signalcomp[i]->edfhdr->recordsize; memset(viewbuf + signalcomp[i]->viewbufoffset + readsize, 0, (signalcomp[i]->records_in_viewbuf * signalcomp[i]->edfhdr->recordsize) - readsize); signalcomp[i]->sample_stop = (dif * signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].smp_per_record) - signalcomp[i]->sample_timeoffset; } else { readsize = signalcomp[i]->records_in_viewbuf * signalcomp[i]->edfhdr->recordsize; signalcomp[i]->sample_stop = signalcomp[i]->samples_on_screen; } l_temp = signalcomp[i]->edfhdr->hdrsize; l_temp += (datarecords * signalcomp[i]->edfhdr->recordsize); fseeko(signalcomp[i]->edfhdr->file_hdl, l_temp, SEEK_SET); if(fread(viewbuf + signalcomp[i]->viewbufoffset, readsize, 1, signalcomp[i]->edfhdr->file_hdl)!=1) { live_stream_active = 0; QMessageBox messagewindow(QMessageBox::Critical, "Error", "A read error occurred. 5"); messagewindow.exec(); remove_all_signals(); return; } } } else { skip = 0; for(j=0; jedfhdr->file_hdl==signalcomp[j]->edfhdr->file_hdl) { skip = 1; break; } } if(signalcomp[i]->edfhdr->viewtime>=0) { datarecords = signalcomp[i]->edfhdr->viewtime / signalcomp[i]->edfhdr->long_data_record_duration; } else { datarecords = 0; } dif = signalcomp[i]->edfhdr->datarecords - datarecords; if(dif<=0) { if(!skip) { memset(viewbuf + signalcomp[i]->viewbufoffset, 0, signalcomp[i]->records_in_viewbuf * signalcomp[i]->edfhdr->recordsize); } signalcomp[i]->sample_stop = 0; } else { if(difrecords_in_viewbuf) { if(!skip) { readsize = dif * signalcomp[i]->edfhdr->recordsize; memset(viewbuf + signalcomp[i]->viewbufoffset + readsize, 0, (signalcomp[i]->records_in_viewbuf * signalcomp[i]->edfhdr->recordsize) - readsize); } signalcomp[i]->sample_stop = (dif * signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].smp_per_record) - signalcomp[i]->sample_timeoffset; } else { if(!skip) { readsize = signalcomp[i]->records_in_viewbuf * signalcomp[i]->edfhdr->recordsize; } signalcomp[i]->sample_stop = signalcomp[i]->samples_on_screen; } if(!skip) { l_temp = signalcomp[i]->edfhdr->hdrsize; l_temp += (datarecords * signalcomp[i]->edfhdr->recordsize); fseeko(signalcomp[i]->edfhdr->file_hdl, l_temp, SEEK_SET); if(fread(viewbuf + signalcomp[i]->viewbufoffset, readsize, 1, signalcomp[i]->edfhdr->file_hdl)!=1) { live_stream_active = 0; QMessageBox messagewindow(QMessageBox::Critical, "Error", "A read error occurred. 6"); messagewindow.exec(); remove_all_signals(); return; } } } } signalcomp[i]->sample_stop += signalcomp[i]->sample_start; } if(signalcomps && (!signal_averaging_active)) { viewtime_string[0] = 0; if(viewtime_indicator_type == 2) { l_temp = (edfheaderlist[sel_viewtime]->viewtime + edfheaderlist[sel_viewtime]->starttime_offset) / TIME_DIMENSION; l_temp += edfheaderlist[sel_viewtime]->utc_starttime; utc_to_date_time(l_temp, &date_time_str); snprintf(viewtime_string, 32, "%2i-%s ", date_time_str.day, date_time_str.month_str); } if((edfheaderlist[sel_viewtime]->viewtime + edfheaderlist[sel_viewtime]->starttime_offset)>=0LL) { if(viewtime_indicator_type > 0) { snprintf(viewtime_string + strlen(viewtime_string), 32, "%2i:%02i:%02i.%04i (", (int)((((edfheaderlist[sel_viewtime]->l_starttime + edfheaderlist[sel_viewtime]->viewtime + edfheaderlist[sel_viewtime]->starttime_offset) / TIME_DIMENSION)/ 3600LL) % 24LL), (int)((((edfheaderlist[sel_viewtime]->l_starttime + edfheaderlist[sel_viewtime]->viewtime + edfheaderlist[sel_viewtime]->starttime_offset) / TIME_DIMENSION) % 3600LL) / 60LL), (int)(((edfheaderlist[sel_viewtime]->l_starttime + edfheaderlist[sel_viewtime]->viewtime + edfheaderlist[sel_viewtime]->starttime_offset) / TIME_DIMENSION) % 60LL), (int)(((edfheaderlist[sel_viewtime]->l_starttime + edfheaderlist[sel_viewtime]->viewtime + edfheaderlist[sel_viewtime]->starttime_offset) % TIME_DIMENSION) / 1000LL)); } snprintf(viewtime_string + strlen(viewtime_string), 32, "%i:%02i:%02i.%04i", (int)((edfheaderlist[sel_viewtime]->viewtime / TIME_DIMENSION)/ 3600LL), (int)(((edfheaderlist[sel_viewtime]->viewtime / TIME_DIMENSION) % 3600LL) / 60LL), (int)((edfheaderlist[sel_viewtime]->viewtime / TIME_DIMENSION) % 60LL), (int)((edfheaderlist[sel_viewtime]->viewtime % TIME_DIMENSION) / 1000LL)); if(viewtime_indicator_type > 0) { sprintf(viewtime_string + strlen(viewtime_string), ")"); } } else { l_temp = edfheaderlist[sel_viewtime]->l_starttime + ((edfheaderlist[sel_viewtime]->viewtime + edfheaderlist[sel_viewtime]->starttime_offset) % (86400LL * TIME_DIMENSION)); if(l_temp<=0) { l_temp += (86400LL * TIME_DIMENSION); } if(viewtime_indicator_type > 0) { snprintf(viewtime_string + strlen(viewtime_string), 32, "%2i:%02i:%02i.%04i (", (int)((((l_temp) / TIME_DIMENSION)/ 3600LL) % 24LL), (int)((((l_temp) / TIME_DIMENSION) % 3600LL) / 60LL), (int)(((l_temp) / TIME_DIMENSION) % 60LL), (int)(((l_temp) % TIME_DIMENSION) / 1000LL)); } l_temp = -edfheaderlist[sel_viewtime]->viewtime; snprintf(viewtime_string + strlen(viewtime_string), 32, "-%i:%02i:%02i.%04i", (int)((l_temp / TIME_DIMENSION)/ 3600LL), (int)(((l_temp / TIME_DIMENSION) % 3600LL) / 60LL), (int)((l_temp / TIME_DIMENSION) % 60LL), (int)((l_temp % TIME_DIMENSION) / 1000LL)); if(viewtime_indicator_type > 0) { sprintf(viewtime_string + strlen(viewtime_string), ")"); } } if(pagetime >= (3600LL * TIME_DIMENSION)) { snprintf(pagetime_string, 32, "%i:%02i:%02i.%04i", ((int)(pagetime / TIME_DIMENSION)) / 3600, (((int)(pagetime / TIME_DIMENSION)) % 3600) / 60, ((int)(pagetime / TIME_DIMENSION)) % 60, (int)((pagetime % TIME_DIMENSION) / 1000LL)); } else { if(pagetime >= (60LL * TIME_DIMENSION)) { snprintf(pagetime_string, 32, "%i:%02i.%04i", ((int)(pagetime / TIME_DIMENSION)) / 60, ((int)(pagetime / TIME_DIMENSION)) % 60, (int)((pagetime % TIME_DIMENSION) / 1000LL)); } else { snprintf(pagetime_string, 32, "%i.%04i sec", (int)(pagetime / TIME_DIMENSION), (int)((pagetime % TIME_DIMENSION) / 1000LL)); } } remove_trailing_zeros(viewtime_string); remove_trailing_zeros(pagetime_string); } if(!signal_averaging_active) { if(print_to_edf_active) { print_to_edf_active = 0; } else { if(signalcomps && (!live_stream_active)) { positionslider->blockSignals(TRUE); long long record_duration = edfheaderlist[sel_viewtime]->long_data_record_duration * edfheaderlist[sel_viewtime]->datarecords; record_duration -= pagetime; if(edfheaderlist[sel_viewtime]->viewtime<=0) { positionslider->setValue(0); } else { if(edfheaderlist[sel_viewtime]->viewtime>=record_duration) { positionslider->setValue(1000000); } else { if(record_durationsetValue(1000000); } else { positionslider->setValue(edfheaderlist[sel_viewtime]->viewtime * 1000000LL / record_duration); } } } slidertoolbar->setEnabled(TRUE); } else { slidertoolbar->setEnabled(FALSE); positionslider->blockSignals(TRUE); } maincurve->drawCurve_stage_1(); if(signalcomps && (!live_stream_active)) { positionslider->blockSignals(FALSE); } } if(spectrumdock->dock->isVisible()) { spectrumdock->rescan(); } } } void UI_Mainwindow::export_to_ascii() { if(!files_open) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "You have to open a file first."); messagewindow.exec(); return; } UI_AsciiExportwindow exportdialog(this); } void UI_Mainwindow::export_ecg_rr_interval_to_ascii() { UI_ECGExport ECG_export(this); } void UI_Mainwindow::export_annotations() { if(!files_open) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "You have to open a file first."); messagewindow.exec(); return; } UI_ExportAnnotationswindow exportAnnotsDialog(this); } void UI_Mainwindow::import_annotations() { UI_ImportAnnotationswindow importAnnotsDialog(this); } void UI_Mainwindow::check_edf_compatibility() { if(!files_open) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "You have to open the file first."); messagewindow.exec(); return; } UI_EDFCompatwindow edfcompatdialog(this); } void UI_Mainwindow::print_to_img_640x480() { maincurve->print_to_image(640, 480); } void UI_Mainwindow::print_to_img_800x600() { maincurve->print_to_image(800, 600); } void UI_Mainwindow::print_to_img_1024x768() { maincurve->print_to_image(1024, 768); } void UI_Mainwindow::print_to_img_1280x1024() { maincurve->print_to_image(1280, 1024); } void UI_Mainwindow::print_to_img_1600x1200() { maincurve->print_to_image(1600, 1200); } long long UI_Mainwindow::get_long_time(char *str) { int i, len, hasdot=0, dotposition=0; long long value=0, radix; str = str + 1; len = strlen(str); for(i=0; i=0; i--) { value += ((long long)(str[i] - 48)) * radix; radix *= 10; } radix = TIME_DIMENSION / 10; for(i=dotposition+1; i=0; i--) { value += ((long long)(str[i] - 48)) * radix; radix *= 10; } } if(str[-1]=='-') value = -value; return(value); } void UI_Mainwindow::get_rgbcolor_settings(struct xml_handle *xml_hdl, const char *id, int cnt, QColor *rgb_color) { char *result; QColor tmp_color; if(xml_goto_nth_element_inside(xml_hdl, id, cnt)) { return; } if(xml_goto_nth_element_inside(xml_hdl, "red", 0)) { return; } result = xml_get_content_of_element(xml_hdl); if(result==NULL) { return; } tmp_color.setRed(atoi(result)); free(result); xml_go_up(xml_hdl); if(xml_goto_nth_element_inside(xml_hdl, "green", 0)) { return; } result = xml_get_content_of_element(xml_hdl); if(result==NULL) { return; } tmp_color.setGreen(atoi(result)); free(result); xml_go_up(xml_hdl); if(xml_goto_nth_element_inside(xml_hdl, "blue", 0)) { return; } result = xml_get_content_of_element(xml_hdl); if(result==NULL) { return; } tmp_color.setBlue(atoi(result)); free(result); *rgb_color = tmp_color; xml_go_up(xml_hdl); xml_go_up(xml_hdl); } void UI_Mainwindow::read_color_settings() { char cfg_path[MAX_PATH_LENGTH], *result; struct xml_handle *xml_hdl; cfg_path[0] = 0; #ifdef Q_WS_X11 strcpy(cfg_path, getenv("HOME")); strcat(cfg_path, "/."); strcat(cfg_path, PROGRAM_NAME); strcat(cfg_path, "/settings.xml"); #endif #ifdef Q_WS_MAC strcpy(cfg_path, getenv("HOME")); strcat(cfg_path, "/."); strcat(cfg_path, PROGRAM_NAME); strcat(cfg_path, "/settings.xml"); #endif #ifdef Q_WS_WIN strcpy(cfg_path, specialFolder(CSIDL_APPDATA).toLocal8Bit().data()); strcat(cfg_path, "\\"); strcat(cfg_path, PROGRAM_NAME); strcat(cfg_path, "\\settings.xml"); #endif xml_hdl = xml_get_handle(cfg_path); if(!xml_hdl) { return; } if(strcmp(xml_hdl->elementname, "config")) { xml_close(xml_hdl); return; } if(xml_goto_nth_element_inside(xml_hdl, "UI", 0)) { xml_close(xml_hdl); return; } if(xml_goto_nth_element_inside(xml_hdl, "colors", 0)) { xml_close(xml_hdl); return; } get_rgbcolor_settings(xml_hdl, "backgroundcolor", 0, &maincurve->backgroundcolor); get_rgbcolor_settings(xml_hdl, "small_ruler_color", 0, &maincurve->small_ruler_color); get_rgbcolor_settings(xml_hdl, "big_ruler_color", 0, &maincurve->big_ruler_color); get_rgbcolor_settings(xml_hdl, "mouse_rect_color", 0, &maincurve->mouse_rect_color); get_rgbcolor_settings(xml_hdl, "text_color", 0, &maincurve->text_color); get_rgbcolor_settings(xml_hdl, "baseline_color", 0, &maincurve->baseline_color); get_rgbcolor_settings(xml_hdl, "annot_marker_color", 0, &maincurve->annot_marker_color); if(xml_goto_nth_element_inside(xml_hdl, "signal_color", 0)) { xml_close(xml_hdl); return; } result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } maincurve->signal_color = atoi(result); free(result); xml_go_up(xml_hdl); if(xml_goto_nth_element_inside(xml_hdl, "floating_ruler_color", 0)) { xml_close(xml_hdl); return; } result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } maincurve->floating_ruler_color = atoi(result); free(result); xml_go_up(xml_hdl); if(xml_goto_nth_element_inside(xml_hdl, "blackwhite_printing", 0)) { xml_close(xml_hdl); return; } result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } maincurve->blackwhite_printing = atoi(result); free(result); xml_go_up(xml_hdl); if(xml_goto_nth_element_inside(xml_hdl, "show_annot_markers", 0)) { xml_close(xml_hdl); return; } result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } show_annot_markers = atoi(result); free(result); xml_go_up(xml_hdl); if(xml_goto_nth_element_inside(xml_hdl, "show_baselines", 0)) { xml_close(xml_hdl); return; } result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } show_baselines = atoi(result); free(result); xml_go_up(xml_hdl); if(xml_goto_nth_element_inside(xml_hdl, "crosshair_1_color", 0)) { xml_close(xml_hdl); return; } result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } maincurve->crosshair_1.color = atoi(result); free(result); xml_go_up(xml_hdl); if(xml_goto_nth_element_inside(xml_hdl, "crosshair_2_color", 0)) { xml_close(xml_hdl); return; } result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } maincurve->crosshair_2.color = atoi(result); free(result); xml_close(xml_hdl); } void UI_Mainwindow::read_recent_file_settings() { int i; char cfg_path[MAX_PATH_LENGTH], *result; struct xml_handle *xml_hdl; cfg_path[0] = 0; #ifdef Q_WS_X11 strcpy(cfg_path, getenv("HOME")); strcat(cfg_path, "/."); strcat(cfg_path, PROGRAM_NAME); strcat(cfg_path, "/settings.xml"); #endif #ifdef Q_WS_MAC strcpy(cfg_path, getenv("HOME")); strcat(cfg_path, "/."); strcat(cfg_path, PROGRAM_NAME); strcat(cfg_path, "/settings.xml"); #endif #ifdef Q_WS_WIN strcpy(cfg_path, specialFolder(CSIDL_APPDATA).toLocal8Bit().data()); strcat(cfg_path, "\\"); strcat(cfg_path, PROGRAM_NAME); strcat(cfg_path, "\\settings.xml"); #endif xml_hdl = xml_get_handle(cfg_path); if(xml_hdl==NULL) { return; } if(strcmp(xml_hdl->elementname, "config")) { xml_close(xml_hdl); return; } if(xml_goto_nth_element_inside(xml_hdl, "UI", 0)) { xml_close(xml_hdl); return; } if(!(xml_goto_nth_element_inside(xml_hdl, "recent_montagedir", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } strncpy(recent_montagedir, result, MAX_PATH_LENGTH); recent_montagedir[MAX_PATH_LENGTH - 1] = 0; free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "recent_savedir", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } strncpy(recent_savedir, result, MAX_PATH_LENGTH); recent_savedir[MAX_PATH_LENGTH - 1] = 0; free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "recent_opendir", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } strncpy(recent_opendir, result, MAX_PATH_LENGTH); recent_opendir[MAX_PATH_LENGTH - 1] = 0; free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "recent_colordir", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } strncpy(recent_colordir, result, MAX_PATH_LENGTH); recent_opendir[MAX_PATH_LENGTH - 1] = 0; free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "recent_file", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } if(result[0] != 0) { strncpy(&recent_file_path[0][0], result, MAX_PATH_LENGTH); recent_file_path[0][MAX_PATH_LENGTH - 1] = 0; recent_filesmenu->addAction(QString::fromLocal8Bit(&recent_file_path[0][0])); free(result); for(i=1; iaddAction(QString::fromLocal8Bit(&recent_file_path[i][0])); free(result); } } else { free(result); } xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "recent_file_mtg", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } strncpy(&recent_file_mtg_path[0][0], result, MAX_PATH_LENGTH); recent_file_mtg_path[0][MAX_PATH_LENGTH - 1] = 0; free(result); for(i=1; ielementname, "config")) { xml_close(xml_hdl); return; } if(!xml_goto_nth_element_inside(xml_hdl, "cfg_app_version", 0)) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } strncpy(cfg_app_version, result, 16); cfg_app_version[16] = 0; free(result); xml_go_up(xml_hdl); } if(xml_goto_nth_element_inside(xml_hdl, "UI", 0)) { xml_close(xml_hdl); return; } if(xml_goto_nth_element_inside(xml_hdl, "pixelsizefactor", 0)) { xml_close(xml_hdl); return; } result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } pixelsizefactor = atof(result); if(pixelsizefactor < 0.00001) { pixelsizefactor = 0.0294382; } free(result); xml_go_up(xml_hdl); if(!(xml_goto_nth_element_inside(xml_hdl, "auto_dpi", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } auto_dpi = atoi(result); if((auto_dpi < 0) || (auto_dpi > 1)) { auto_dpi = 1; } free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "x_pixelsizefactor", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } x_pixelsizefactor = atof(result); if(x_pixelsizefactor < 0.00001) { x_pixelsizefactor = 0.0294382; } free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "clip_to_pane", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } clip_to_pane = atoi(result); if((clip_to_pane < 0) || (clip_to_pane > 1)) { clip_to_pane = 0; } free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "auto_reload_mtg", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } auto_reload_mtg = atoi(result); if((auto_reload_mtg < 0) || (auto_reload_mtg > 1)) { auto_reload_mtg = 1; } free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "read_biosemi_status_signal", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } read_biosemi_status_signal = atoi(result); if((read_biosemi_status_signal < 0) || (read_biosemi_status_signal > 1)) { read_biosemi_status_signal = 1; } free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "read_nk_trigger_signal", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } read_nk_trigger_signal = atoi(result); if((read_nk_trigger_signal < 0) || (read_nk_trigger_signal > 1)) { read_nk_trigger_signal = 1; } free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "maxfilesize_to_readin_annotations", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } maxfilesize_to_readin_annotations = atoll(result); if((maxfilesize_to_readin_annotations < 104857600LL) || (maxfilesize_to_readin_annotations > 10485760000LL)) { maxfilesize_to_readin_annotations = 10485760000LL; } free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "use_threads", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } use_threads = atoi(result); if((use_threads < 0) || (use_threads > 1)) { use_threads = 1; } free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "spectrummarkerblock", 0))) { if(xml_goto_nth_element_inside(xml_hdl, "items", 0)) { xml_close(xml_hdl); return; } result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } if((atoi(result) > MAXSPECTRUMMARKERS) || (atoi(result) < 0)) { xml_close(xml_hdl); free(result); return; } spectrum_colorbar->items = atoi(result); free(result); xml_go_up(xml_hdl); if(xml_goto_nth_element_inside(xml_hdl, "method", 0)) { xml_close(xml_hdl); return; } result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } if((atoi(result) > 2) || (atoi(result) < 0)) { xml_close(xml_hdl); free(result); return; } spectrum_colorbar->method = atoi(result); free(result); xml_go_up(xml_hdl); if(xml_goto_nth_element_inside(xml_hdl, "frequency", 0)) { xml_close(xml_hdl); return; } result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } if((atof(result) > 1000000.0) || (atof(result) < 0.00001)) { xml_close(xml_hdl); free(result); return; } spectrum_colorbar->freq[0] = atof(result); free(result); for(i=1; i < spectrum_colorbar->items; i++) { if(xml_goto_next_element_with_same_name(xml_hdl)) { xml_close(xml_hdl); return; } result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } if(i < spectrum_colorbar->items) { if((atof(result) > 1000000.0) || (atof(result) <= spectrum_colorbar->freq[i-1])) { xml_close(xml_hdl); free(result); return; } } spectrum_colorbar->freq[i] = atof(result); free(result); } xml_go_up(xml_hdl); if(xml_goto_nth_element_inside(xml_hdl, "color", 0)) { xml_close(xml_hdl); return; } result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } if((atoi(result) > 18) || (atoi(result) < 2)) { xml_close(xml_hdl); free(result); return; } spectrum_colorbar->color[0] = atoi(result); free(result); for(i=1; i < spectrum_colorbar->items; i++) { if(xml_goto_next_element_with_same_name(xml_hdl)) { xml_close(xml_hdl); return; } result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } if((atoi(result) > 18) || (atoi(result) < 2)) { xml_close(xml_hdl); free(result); return; } spectrum_colorbar->color[i] = atoi(result); free(result); } xml_go_up(xml_hdl); if(!(xml_goto_nth_element_inside(xml_hdl, "label", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } strncpy(spectrum_colorbar->label[0], result, 16); spectrum_colorbar->label[0][16] = 0; free(result); for(i=1; i < spectrum_colorbar->items; i++) { if(xml_goto_next_element_with_same_name(xml_hdl)) { xml_close(xml_hdl); return; } result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } strncpy(spectrum_colorbar->label[i], result, 16); spectrum_colorbar->label[i][16] = 0; free(result); } xml_go_up(xml_hdl); } } xml_go_up(xml_hdl); if(!(xml_goto_nth_element_inside(xml_hdl, "maxdftblocksize", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } if(atoi(result) < 10) { xml_close(xml_hdl); free(result); return; } maxdftblocksize = atoi(result); free(result); } xml_go_up(xml_hdl); if(!(xml_goto_nth_element_inside(xml_hdl, "annotations_import_var", 0))) { if(!(xml_goto_nth_element_inside(xml_hdl, "format", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } import_annotations_var->format = atoi(result); if((import_annotations_var->format < 0) || (import_annotations_var->format > 3)) { import_annotations_var->format = 1; } free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "onsettimeformat", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } import_annotations_var->onsettimeformat = atoi(result); free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "onsetcolumn", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } import_annotations_var->onsetcolumn = atoi(result); free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "descriptioncolumn", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } import_annotations_var->descriptioncolumn = atoi(result); free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "useduration", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } import_annotations_var->useduration = atoi(result); if(import_annotations_var->useduration != 1) { import_annotations_var->useduration = 0; } free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "durationcolumn", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } import_annotations_var->durationcolumn = atoi(result); if(import_annotations_var->durationcolumn < 0) { import_annotations_var->durationcolumn = 0; } free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "datastartline", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } import_annotations_var->datastartline = atoi(result); free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "separator", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } strncpy(import_annotations_var->separator, result, 3); import_annotations_var->separator[3] = 0; free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "dceventbittime", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } import_annotations_var->dceventbittime = atoi(result); free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "triggerlevel", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } import_annotations_var->triggerlevel = atof(result); free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "manualdescription", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } import_annotations_var->manualdescription = atoi(result); if((import_annotations_var->manualdescription < 0) || (import_annotations_var->manualdescription > 1)) { import_annotations_var->manualdescription = 0; } free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "description", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } strncpy(import_annotations_var->description, result, 20); import_annotations_var->description[20] = 0; free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "ignoreconsecutive", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } import_annotations_var->ignoreconsecutive = atoi(result); if(import_annotations_var->ignoreconsecutive != 1) { import_annotations_var->ignoreconsecutive = 0; } free(result); xml_go_up(xml_hdl); } xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "annotations_export_var", 0))) { if(!(xml_goto_nth_element_inside(xml_hdl, "separator", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } export_annotations_var->separator = atoi(result); free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "format", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } export_annotations_var->format = atoi(result); free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "duration", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } export_annotations_var->duration = atoi(result); free(result); xml_go_up(xml_hdl); } xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "live_stream_update_interval", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } live_stream_update_interval = atoi(result); if((live_stream_update_interval < 100) || (live_stream_update_interval > 3000)) { live_stream_update_interval = 500; } free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "powerlinefreq", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } powerlinefreq = atoi(result); if((powerlinefreq != 50) && (powerlinefreq != 60)) { powerlinefreq = 50; } free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "mousewheelsens", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } mousewheelsens = atoi(result); if((mousewheelsens < 0) || (mousewheelsens > 100)) { mousewheelsens = 10; } free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "average_period", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } average_period = atof(result); free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "average_ratio", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } average_ratio = atoi(result); if((average_ratio < 0) || (average_ratio > 2)) { average_ratio = 0; } free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "average_upsidedown", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } if(atoi(result) == 1) { average_upsidedown = 1; } else { average_upsidedown = 0; } free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "average_bw", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } if(atoi(result) == 1) { average_bw = 1; } else { average_bw = 0; } free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "spectrum_bw", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } if(atoi(result) == 1) { spectrum_bw = 1; } else { spectrum_bw = 0; } free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "spectrum_sqrt", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } if(atoi(result) == 1) { spectrum_sqrt = 1; } else { spectrum_sqrt = 0; } free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "z_score_var.zscore_page_len", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } z_score_var.zscore_page_len = atoi(result); if((z_score_var.zscore_page_len < 10) || (z_score_var.zscore_page_len > 60)) { z_score_var.zscore_page_len = 30; } free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "z_score_var.z_threshold", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } z_score_var.z_threshold = atof(result); if((z_score_var.z_threshold < -0.5) || (z_score_var.z_threshold > 0.5)) { z_score_var.z_threshold = 0.0; } free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "z_score_var.crossoverfreq", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } z_score_var.crossoverfreq = atof(result); if((z_score_var.crossoverfreq < 5.0) || (z_score_var.crossoverfreq > 9.5)) { z_score_var.crossoverfreq = 7.5; } free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "z_score_var.z_hysteresis", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } z_score_var.z_hysteresis = atof(result); if((z_score_var.z_hysteresis < 0.0) || (z_score_var.z_hysteresis > 0.25)) { z_score_var.z_hysteresis = 0.0; } free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "z_score_var.zscore_error_detection", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } z_score_var.zscore_error_detection = atoi(result); if((z_score_var.zscore_error_detection < 50) || (z_score_var.zscore_error_detection > 100)) { z_score_var.zscore_error_detection = 50; } free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "raw2edf_var", 0))) { if(!(xml_goto_nth_element_inside(xml_hdl, "sf", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } raw2edf_var.sf = atoi(result); if(raw2edf_var.sf < 1) raw2edf_var.sf = 1; if(raw2edf_var.sf > 1000000) raw2edf_var.sf = 1000000; free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "chns", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } raw2edf_var.chns = atoi(result); if(raw2edf_var.chns < 1) raw2edf_var.chns = 1; if(raw2edf_var.chns > 256) raw2edf_var.chns = 256; free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "phys_max", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } raw2edf_var.phys_max = atoi(result); if(raw2edf_var.phys_max < 1) raw2edf_var.phys_max = 1; if(raw2edf_var.phys_max > 10000000) raw2edf_var.phys_max = 10000000; free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "straightbinary", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } raw2edf_var.straightbinary = atoi(result); if(raw2edf_var.straightbinary < 0) raw2edf_var.straightbinary = 0; if(raw2edf_var.straightbinary > 1) raw2edf_var.straightbinary = 1; free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "endianness", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } raw2edf_var.endianness = atoi(result); if(raw2edf_var.endianness < 0) raw2edf_var.endianness = 0; if(raw2edf_var.endianness > 1) raw2edf_var.endianness = 1; free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "samplesize", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } raw2edf_var.samplesize = atoi(result); if(raw2edf_var.samplesize < 1) raw2edf_var.samplesize = 1; if(raw2edf_var.samplesize > 2) raw2edf_var.samplesize = 2; free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "offset", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } raw2edf_var.offset = atoi(result); if(raw2edf_var.offset < 0) raw2edf_var.offset = 0; if(raw2edf_var.offset > 1000000) raw2edf_var.offset = 1000000; free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "skipblocksize", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } raw2edf_var.skipblocksize = atoi(result); if(raw2edf_var.skipblocksize < 0) raw2edf_var.skipblocksize = 0; if(raw2edf_var.skipblocksize > 1000000) raw2edf_var.skipblocksize = 1000000; free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "skipbytes", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } raw2edf_var.skipbytes = atoi(result); if(raw2edf_var.skipbytes < 1) raw2edf_var.skipbytes = 1; if(raw2edf_var.skipbytes > 1000000) raw2edf_var.skipbytes = 1000000; free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "phys_dim", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } strncpy(raw2edf_var.phys_dim, result, 16); raw2edf_var.phys_dim[15] = 0; latin1_to_ascii(raw2edf_var.phys_dim, 16); remove_leading_spaces(raw2edf_var.phys_dim); remove_trailing_spaces(raw2edf_var.phys_dim); free(result); xml_go_up(xml_hdl); } xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "check_for_updates", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } check_for_updates = atoi(result); if((check_for_updates < 0) || (check_for_updates > 1)) check_for_updates = 1; free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "viewtime_indicator_type", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } viewtime_indicator_type = atoi(result); if((viewtime_indicator_type < 0) || (viewtime_indicator_type > 2)) viewtime_indicator_type = 1; free(result); xml_go_up(xml_hdl); } if(!(xml_goto_nth_element_inside(xml_hdl, "mainwindow_title_type", 0))) { result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } mainwindow_title_type = atoi(result); if((mainwindow_title_type < 0) || (mainwindow_title_type > 2)) mainwindow_title_type = 1; free(result); xml_go_up(xml_hdl); } xml_close(xml_hdl); } void UI_Mainwindow::recent_file_action_func(QAction *action) { strcpy(path, action->text().toLocal8Bit().data()); cmdlineargument = 1; open_new_file(); } void UI_Mainwindow::write_settings() { int i, len; char cfg_path[MAX_PATH_LENGTH], str[1024]; FILE *cfgfile; cfg_path[0] = 0; #ifdef Q_WS_X11 strcpy(cfg_path, getenv("HOME")); strcat(cfg_path, "/."); strcat(cfg_path, PROGRAM_NAME); mkdir(cfg_path, S_IRWXU); strcat(cfg_path, "/settings.xml"); #endif #ifdef Q_WS_MAC strcpy(cfg_path, getenv("HOME")); strcat(cfg_path, "/."); strcat(cfg_path, PROGRAM_NAME); mkdir(cfg_path, S_IRWXU); strcat(cfg_path, "/settings.xml"); #endif #ifdef Q_WS_WIN strcpy(cfg_path, specialFolder(CSIDL_APPDATA).toLocal8Bit().data()); strcat(cfg_path, "\\"); strcat(cfg_path, PROGRAM_NAME); _mkdir(cfg_path); strcat(cfg_path, "\\settings.xml"); #endif cfgfile = fopeno(cfg_path, "wb"); if(cfgfile) { fprintf(cfgfile, "\n" "\n" " " PROGRAM_NAME " " PROGRAM_VERSION "\n" " \n" " \n"); fprintf(cfgfile, " \n" " %i\n" " %i\n" " %i\n" " \n", maincurve->backgroundcolor.red(), maincurve->backgroundcolor.green(), maincurve->backgroundcolor.blue()); fprintf(cfgfile, " \n" " %i\n" " %i\n" " %i\n" " \n", maincurve->small_ruler_color.red(), maincurve->small_ruler_color.green(), maincurve->small_ruler_color.blue()); fprintf(cfgfile, " \n" " %i\n" " %i\n" " %i\n" " \n", maincurve->big_ruler_color.red(), maincurve->big_ruler_color.green(), maincurve->big_ruler_color.blue()); fprintf(cfgfile, " \n" " %i\n" " %i\n" " %i\n" " \n", maincurve->mouse_rect_color.red(), maincurve->mouse_rect_color.green(), maincurve->mouse_rect_color.blue()); fprintf(cfgfile, " \n" " %i\n" " %i\n" " %i\n" " \n", maincurve->text_color.red(), maincurve->text_color.green(), maincurve->text_color.blue()); fprintf(cfgfile, " \n" " %i\n" " %i\n" " %i\n" " \n", maincurve->baseline_color.red(), maincurve->baseline_color.green(), maincurve->baseline_color.blue()); fprintf(cfgfile, " \n" " %i\n" " %i\n" " %i\n" " \n", maincurve->annot_marker_color.red(), maincurve->annot_marker_color.green(), maincurve->annot_marker_color.blue()); fprintf(cfgfile, " %i\n", maincurve->signal_color); fprintf(cfgfile, " %i\n", maincurve->crosshair_1.color); fprintf(cfgfile, " %i\n", maincurve->crosshair_2.color); fprintf(cfgfile, " %i\n", maincurve->floating_ruler_color); fprintf(cfgfile, " %i\n", maincurve->blackwhite_printing); fprintf(cfgfile, " %i\n", show_annot_markers); fprintf(cfgfile, " %i\n", show_baselines); fprintf(cfgfile, " %i\n", clip_to_pane); fprintf(cfgfile, " %i\n", auto_reload_mtg); fprintf(cfgfile, " %i\n", read_biosemi_status_signal); fprintf(cfgfile, " %i\n", read_nk_trigger_signal); fprintf(cfgfile, " %i\n", use_threads); #ifdef Q_WS_WIN fprintf(cfgfile, " %I64d\n", maxfilesize_to_readin_annotations); #else fprintf(cfgfile, " %lli\n", maxfilesize_to_readin_annotations); #endif len = strlen(path); for(i=len-1; i>=0; i--) { if((path[i] == '/')||(path[i] == '\\')) { break; } } path[i+1] = 0; fprintf(cfgfile, " \n %.10f\n %i\n %.10f\n ", pixelsizefactor, auto_dpi, x_pixelsizefactor); xml_fwrite_encode_entity(cfgfile, path); fprintf(cfgfile, "\n"); for(i=0; i"); xml_fwrite_encode_entity(cfgfile, &recent_file_path[i][0]); fprintf(cfgfile, "\n"); } for(i=0; i"); xml_fwrite_encode_entity(cfgfile, &recent_file_mtg_path[i][0]); fprintf(cfgfile, "\n"); } fprintf(cfgfile, " "); xml_fwrite_encode_entity(cfgfile, recent_montagedir); fprintf(cfgfile, "\n"); fprintf(cfgfile, " "); xml_fwrite_encode_entity(cfgfile, recent_savedir); fprintf(cfgfile, "\n"); fprintf(cfgfile, " "); xml_fwrite_encode_entity(cfgfile, recent_opendir); fprintf(cfgfile, "\n"); fprintf(cfgfile, " "); xml_fwrite_encode_entity(cfgfile, recent_colordir); fprintf(cfgfile, "\n"); for(i=0; i < MAXPREDEFINEDMONTAGES; i++) { fprintf(cfgfile, " "); xml_fwrite_encode_entity(cfgfile, &predefined_mtg_path[i][0]); fprintf(cfgfile, "\n"); } fprintf(cfgfile, " \n"); fprintf(cfgfile, " %i\n", spectrum_colorbar->items); for(i=0; i < MAXSPECTRUMMARKERS; i++) { fprintf(cfgfile, " %f\n", spectrum_colorbar->freq[i]); } for(i=0; i < MAXSPECTRUMMARKERS; i++) { fprintf(cfgfile, " %i\n", spectrum_colorbar->color[i]); } for(i=0; i < MAXSPECTRUMMARKERS; i++) { fprintf(cfgfile, " \n"); } fprintf(cfgfile, " %i\n", spectrum_colorbar->method); fprintf(cfgfile, " \n"); fprintf(cfgfile, " %i\n", maxdftblocksize); fprintf(cfgfile, " \n"); fprintf(cfgfile, " %i\n", import_annotations_var->format); fprintf(cfgfile, " %i\n", import_annotations_var->onsettimeformat); fprintf(cfgfile, " %i\n", import_annotations_var->onsetcolumn); fprintf(cfgfile, " %i\n", import_annotations_var->descriptioncolumn); fprintf(cfgfile, " %i\n", import_annotations_var->useduration); fprintf(cfgfile, " %i\n", import_annotations_var->durationcolumn); fprintf(cfgfile, " %i\n", import_annotations_var->datastartline); xml_strcpy_encode_entity(str, import_annotations_var->separator); fprintf(cfgfile, " %s\n", str); fprintf(cfgfile, " %i\n", import_annotations_var->dceventbittime); fprintf(cfgfile, " %.12f\n", import_annotations_var->triggerlevel); fprintf(cfgfile, " %i\n", import_annotations_var->manualdescription); xml_strcpy_encode_entity(str, import_annotations_var->description); fprintf(cfgfile, " %s\n", str); fprintf(cfgfile, " %i\n", import_annotations_var->ignoreconsecutive); fprintf(cfgfile, " \n"); fprintf(cfgfile, " \n"); fprintf(cfgfile, " %i\n", export_annotations_var->separator); fprintf(cfgfile, " %i\n", export_annotations_var->format); fprintf(cfgfile, " %i\n", export_annotations_var->duration); fprintf(cfgfile, " \n"); fprintf(cfgfile, " %i\n", live_stream_update_interval); fprintf(cfgfile, " %i\n", powerlinefreq); fprintf(cfgfile, " %i\n", mousewheelsens); fprintf(cfgfile, " %f\n", average_period); fprintf(cfgfile, " %i\n", average_ratio); fprintf(cfgfile, " %i\n", average_upsidedown); fprintf(cfgfile, " %i\n", average_bw); fprintf(cfgfile, " %i\n", spectrum_bw); fprintf(cfgfile, " %i\n", spectrum_sqrt); fprintf(cfgfile, " %f\n", z_score_var.crossoverfreq); fprintf(cfgfile, " %f\n", z_score_var.z_threshold); fprintf(cfgfile, " %i\n", z_score_var.zscore_page_len); fprintf(cfgfile, " %i\n", z_score_var.zscore_error_detection); fprintf(cfgfile, " %f\n", z_score_var.z_hysteresis); fprintf(cfgfile, " \n"); fprintf(cfgfile, " %i\n", raw2edf_var.sf); fprintf(cfgfile, " %i\n", raw2edf_var.chns); fprintf(cfgfile, " %i\n", raw2edf_var.phys_max); fprintf(cfgfile, " %i\n", raw2edf_var.straightbinary); fprintf(cfgfile, " %i\n", raw2edf_var.endianness); fprintf(cfgfile, " %i\n", raw2edf_var.samplesize); fprintf(cfgfile, " %i\n", raw2edf_var.offset); fprintf(cfgfile, " %i\n", raw2edf_var.skipblocksize); fprintf(cfgfile, " %i\n", raw2edf_var.skipbytes); xml_strcpy_encode_entity(str, raw2edf_var.phys_dim); fprintf(cfgfile, " %s\n", str); fprintf(cfgfile, " \n"); fprintf(cfgfile, " %i\n", check_for_updates); fprintf(cfgfile, " %i\n", viewtime_indicator_type); fprintf(cfgfile, " %i\n", mainwindow_title_type); fprintf(cfgfile, " \n\n"); fclose(cfgfile); } } void UI_Mainwindow::save_montage() { if(!files_open) return; if(!signalcomps) return; UI_SaveMontagewindow save_mtg(this); } void UI_Mainwindow::load_montage() { if(!files_open) return; UI_LoadMontagewindow load_mtg(this); } void UI_Mainwindow::view_montage() { UI_ViewMontagewindow view_mtg(this); } void UI_Mainwindow::show_this_montage() { UI_ShowActualMontagewindow show_mtg(this); } void UI_Mainwindow::print_to_edf() { print_screen_to_edf(this); } void UI_Mainwindow::print_to_bdf() { print_screen_to_bdf(this); } void UI_Mainwindow::set_dc_offset_to_zero() { int i; if(!signalcomps) { return; } for(i=0; iscreen_offset = 0.0; } maincurve->drawCurve_stage_1(); } void UI_Mainwindow::show_help() { #ifdef Q_WS_X11 QDesktopServices::openUrl(QUrl("file:///usr/share/doc/edfbrowser/manual.html")); #endif #ifdef Q_WS_WIN char path[MAX_PATH_LENGTH]; strcpy(path, "file:///"); strcat(path, specialFolder(CSIDL_PROGRAM_FILES).toLocal8Bit().data()); strcat(path, "\\EDFbrowser\\manual.html"); QDesktopServices::openUrl(QUrl(path)); #endif } void UI_Mainwindow::show_kb_shortcuts() { UI_Messagewindow popuperror("Keyboard shortcuts", "PgDn\tnext page\n" "PgUp\tformer page\n" "Right Arrow\tshift right one tenth of pagetime\n" "Left Arrow\tshift left one tenth of pagetime\n" "Plus\tincrease sensitivity\n" "Minus\tdecrease sensitivity\n" "Up Arrow\tshift up\n" "Down Arrow\tshift down\n" "Ctrl-Home\tgo to start of file\n" "Ctrl-End\tgo to end of file\n" "Ctrl++\tzoom in\n" "Ctrl+-\tzoom out\n" "F1 - F8\tload predefined montage\n" "Esc\tremove crosshairs or floating ruler\n" "\nafter zooming in by dragging a rectangle:\n" "Backspace\tzoom back\n" "Insert\tzoom in\n" #ifdef Q_WS_WIN "\nCtrl+O\tOpen a file\n" "Ctrl+F4\tClose all files\n" "Alt+F4\tExit program\n" #else "\nCtrl+O\tOpen a file\n" "Ctrl+W\tClose all files\n" "Ctrl+Q\tExit program\n" #endif "\nMousewheel\tshift left or right\n" "Ctrl+Mousewheel\tzoom in or out"); } #ifdef Q_WS_WIN QString UI_Mainwindow::specialFolder(int type) { QString result; QLibrary library(QLatin1String("shell32")); QT_WA( { typedef BOOL (WINAPI*GetSpecialFolderPath)(HWND, LPTSTR, int, BOOL); GetSpecialFolderPath SHGetSpecialFolderPath = (GetSpecialFolderPath)library.resolve("SHGetSpecialFolderPathW"); if (SHGetSpecialFolderPath) { TCHAR path[MAX_PATH]; SHGetSpecialFolderPath(0, path, type, FALSE); result = QString::fromUtf16((ushort*)path); } } , { typedef BOOL (WINAPI*GetSpecialFolderPath)(HWND, char*, int, BOOL); GetSpecialFolderPath SHGetSpecialFolderPath = (GetSpecialFolderPath)library.resolve("SHGetSpecialFolderPathA"); if (SHGetSpecialFolderPath) { char path[MAX_PATH]; SHGetSpecialFolderPath(0, path, type, FALSE); result = QString::fromLocal8Bit(path); } } ); if (result.isEmpty()) { result = QLatin1String("C:\\temp"); } return result; } #endif int UI_Mainwindow::file_is_opened(const char *o_path) { int i; for(i=0; ifilename, o_path)) { return(1); } } return(0); } void UI_Mainwindow::organize_signals() { UI_SignalChooser signalchooser(this, 3); } void UI_Mainwindow::edfplus_annotation_remove_duplicates() { int i, j, k, list_size, dup_cnt=0; char str[256]; struct annotationblock **list, *annot, *annot_cmp; QProgressDialog progress("Checking for duplicates...", "Abort", 0, 10, this); progress.setWindowModality(Qt::WindowModal); progress.setMinimumDuration(200); for(k=0; kprocessEvents(); if(progress.wasCanceled() == TRUE) { break; } annot_cmp = edfplus_annotation_item(list, j); for(i=j; ionset != annot_cmp->onset) continue; if(annot->file_num != annot_cmp->file_num) continue; if(strcmp(annot->annotation, annot_cmp->annotation)) continue; if(strcmp(annot->duration, annot_cmp->duration)) continue; edfplus_annotation_delete(list, i); dup_cnt++; list_size--; if(j) j--; if(i) i--; } } } } progress.reset(); if(dup_cnt) { for(k=0; kupdateList(); } } annotations_edited = 1; save_act->setEnabled(TRUE); } snprintf(str, 256, "Removed %i duplicates from the annotationlist(s)", dup_cnt); QMessageBox messagewindow(QMessageBox::Information, "Ready", str); messagewindow.exec(); } struct signalcompblock * UI_Mainwindow::create_signalcomp_copy(struct signalcompblock *original_signalcomp) { int i; char spec_str[256], *filter_spec, *err; struct signalcompblock *newsignalcomp; if(signalcomps >= MAXSIGNALS) { return(NULL); } if(original_signalcomp->ecg_filter != NULL) { return(NULL); } if(original_signalcomp->zratio_filter != NULL) { return(NULL); } newsignalcomp = (struct signalcompblock *)calloc(1, sizeof(struct signalcompblock)); if(newsignalcomp == NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "malloc() error"); messagewindow.exec(); return(NULL); } memcpy(newsignalcomp, original_signalcomp, sizeof(struct signalcompblock)); for(i=0; ifilter_cnt; i++) { newsignalcomp->filter[i] = create_filter_copy(original_signalcomp->filter[i]); if(newsignalcomp->filter[i] == NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "malloc() error"); messagewindow.exec(); free(signalcomp); return(NULL); } } for(i=0; iravg_filter_cnt; i++) { newsignalcomp->ravg_filter[i] = create_ravg_filter_copy(original_signalcomp->ravg_filter[i]); if(newsignalcomp->ravg_filter[i] == NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "malloc() error"); messagewindow.exec(); free(signalcomp); return(NULL); } } for(i=0; ifidfilter_cnt; i++) { if(newsignalcomp->fidfilter_type[i] == 0) { if(newsignalcomp->fidfilter_model[i] == 0) { sprintf(spec_str, "HpBu%i/%f", newsignalcomp->fidfilter_order[i], newsignalcomp->fidfilter_freq[i]); } if(newsignalcomp->fidfilter_model[i] == 1) { sprintf(spec_str, "HpCh%i/%f/%f", newsignalcomp->fidfilter_order[i], newsignalcomp->fidfilter_ripple[i], newsignalcomp->fidfilter_freq[i]); } if(newsignalcomp->fidfilter_model[i] == 2) { sprintf(spec_str, "HpBe%i/%f", newsignalcomp->fidfilter_order[i], newsignalcomp->fidfilter_freq[i]); } } if(newsignalcomp->fidfilter_type[i] == 1) { if(newsignalcomp->fidfilter_model[i] == 0) { sprintf(spec_str, "LpBu%i/%f", newsignalcomp->fidfilter_order[i], newsignalcomp->fidfilter_freq[i]); } if(newsignalcomp->fidfilter_model[i] == 1) { sprintf(spec_str, "LpCh%i/%f/%f", newsignalcomp->fidfilter_order[i], newsignalcomp->fidfilter_ripple[i], newsignalcomp->fidfilter_freq[i]); } if(newsignalcomp->fidfilter_model[i] == 2) { sprintf(spec_str, "LpBe%i/%f", newsignalcomp->fidfilter_order[i], newsignalcomp->fidfilter_freq[i]); } } if(newsignalcomp->fidfilter_type[i] == 2) { if(newsignalcomp->fidfilter_model[i] == 0) { sprintf(spec_str, "BsRe/%i/%f", newsignalcomp->fidfilter_order[i], newsignalcomp->fidfilter_freq[i]); } } if(newsignalcomp->fidfilter_type[i] == 3) { if(newsignalcomp->fidfilter_model[i] == 0) { sprintf(spec_str, "BpBu%i/%f-%f", newsignalcomp->fidfilter_order[i], newsignalcomp->fidfilter_freq[i], newsignalcomp->fidfilter_freq2[i]); } if(newsignalcomp->fidfilter_model[i] == 1) { sprintf(spec_str, "BpCh%i/%f/%f-%f", newsignalcomp->fidfilter_order[i], newsignalcomp->fidfilter_ripple[i], newsignalcomp->fidfilter_freq[i], newsignalcomp->fidfilter_freq2[i]); } if(newsignalcomp->fidfilter_model[i] == 2) { sprintf(spec_str, "BpBe%i/%f-%f", newsignalcomp->fidfilter_order[i], newsignalcomp->fidfilter_freq[i], newsignalcomp->fidfilter_freq2[i]); } } if(newsignalcomp->fidfilter_type[i] == 4) { if(newsignalcomp->fidfilter_model[i] == 0) { sprintf(spec_str, "BsBu%i/%f-%f", newsignalcomp->fidfilter_order[i], newsignalcomp->fidfilter_freq[i], newsignalcomp->fidfilter_freq2[i]); } if(newsignalcomp->fidfilter_model[i] == 1) { sprintf(spec_str, "BsCh%i/%f/%f-%f", newsignalcomp->fidfilter_order[i], newsignalcomp->fidfilter_ripple[i], newsignalcomp->fidfilter_freq[i], newsignalcomp->fidfilter_freq2[i]); } if(newsignalcomp->fidfilter_model[i] == 2) { sprintf(spec_str, "BsBe%i/%f-%f", newsignalcomp->fidfilter_order[i], newsignalcomp->fidfilter_freq[i], newsignalcomp->fidfilter_freq2[i]); } } filter_spec = spec_str; err = fid_parse(((double)(newsignalcomp->edfhdr->edfparam[newsignalcomp->edfsignal[0]].smp_per_record)) / newsignalcomp->edfhdr->data_record_duration, &filter_spec, &newsignalcomp->fidfilter[i]); if(err != NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", err); messagewindow.exec(); free(err); free(signalcomp); return(NULL); } newsignalcomp->fid_run[i] = fid_run_new(newsignalcomp->fidfilter[i], &newsignalcomp->fidfuncp[i]); newsignalcomp->fidbuf[i] = fid_run_newbuf(newsignalcomp->fid_run[i]); newsignalcomp->fidbuf2[i] = fid_run_newbuf(newsignalcomp->fid_run[i]); // memcpy(newsignalcomp->fidbuf[i], original_signalcomp->fidbuf[i], fid_run_bufsize(original_signalcomp->fid_run[i])); // memcpy(newsignalcomp->fidbuf2[i], original_signalcomp->fidbuf2[i], fid_run_bufsize(original_signalcomp->fid_run[i])); } signalcomp[signalcomps] = newsignalcomp; signalcomps++; return(newsignalcomp); } edfbrowser_153_source/PaxHeaders.2978/popup_save_cancelwindow.h0000644000175000001440000000013212251654530023236 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/popup_save_cancelwindow.h0000644000175000001440000000342412251654530022772 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef POPUP_CANCELSAVEFORM1_H #define POPUP_CANCELSAVEFORM1_H #include #include #include #include #include #include #include "global.h" class UI_CancelSavewindow : public QObject { Q_OBJECT public: UI_CancelSavewindow(const char *, const char *, const char *, const char *, int *); private: QDialog *MessageDialog; QLabel *Label1; QPushButton *pushButton1, *pushButton2; int *buttonnr; private slots: void button1Clicked(); void button2Clicked(); }; #endif edfbrowser_153_source/PaxHeaders.2978/check_edf_file.cpp0000644000175000001440000000013212251654530021545 xustar000000000000000030 mtime=1386699096.477032522 30 atime=1386699096.477032522 30 ctime=1386699096.477032522 edfbrowser_153_source/check_edf_file.cpp0000644000175000001440000014145212251654530021305 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "check_edf_file.h" #if defined(__APPLE__) || defined(__MACH__) || defined(__APPLE_CC__) #define fopeno fopen #else #define fseeko fseeko64 #define ftello ftello64 #define fopeno fopen64 #endif struct edfhdrblock * EDFfileCheck::check_edf_file(FILE *inputfile, char *txt_string, int live_stream) { int i, j, p, r=0, n, dotposition, error; char *edf_hdr, scratchpad[128], scratchpad2[64]; long long l_tmp, l_tmp2; struct date_time_struct date_time; /***************** check header ******************************/ edf_hdr = (char *)calloc(1, 256); if(edf_hdr==NULL) { sprintf(txt_string, "Memory allocation error. (edf_hdr)"); return(NULL); } edfhdr = (struct edfhdrblock *)calloc(1, sizeof(struct edfhdrblock)); if(edfhdr==NULL) { sprintf(txt_string, "Memory allocation error. (edfhdr)"); return(NULL); } rewind(inputfile); if(fread(edf_hdr, 256, 1, inputfile)!=1) { sprintf(txt_string, "Error, reading file"); free(edf_hdr); free(edfhdr); return(NULL); } /**************************** VERSION ***************************************/ strncpy(scratchpad, edf_hdr, 8); scratchpad[8] = 0; if(((signed char *)scratchpad)[0]==-1) // BDF-file { for(i=1; i<8; i++) { if((scratchpad[i]<32)||(scratchpad[i]>126)) { sprintf(txt_string, "Error, %ith character of version field is not a valid 7-bit ASCII character.", i + 1); free(edf_hdr); free(edfhdr); return(NULL); } } if(strcmp(scratchpad + 1, "BIOSEMI")) { sprintf(txt_string, "Error, header has unknown version: \".%s\",\n" "expected \".BIOSEMI\"", scratchpad + 1); free(edf_hdr); free(edfhdr); return(NULL); } edfhdr->bdf = 1; } else // EDF-file { for(i=0; i<8; i++) { if((scratchpad[i]<32)||(scratchpad[i]>126)) { sprintf(txt_string, "Error, %ith character of version field is not a valid 7-bit ASCII character.", i + 1); free(edf_hdr); free(edfhdr); return(NULL); } } if(strcmp(scratchpad, "0 ")) { sprintf(txt_string, "Error, header has unknown version: \"%s\",\n" "expected \"0 \"", scratchpad); free(edf_hdr); free(edfhdr); return(NULL); } edfhdr->edf = 1; } strncpy(edfhdr->version, edf_hdr, 8); edfhdr->version[8] = 0; if(edfhdr->bdf) edfhdr->version[0] = '.'; /********************* PATIENTNAME *********************************************/ strncpy(scratchpad, edf_hdr + 8, 80); scratchpad[80] = 0; for(i=0; i<80; i++) { if((((unsigned char *)scratchpad)[i]<32)||(((unsigned char *)scratchpad)[i]>126)) { sprintf(txt_string, "Error, %ith character of local patient identification field is not a valid 7-bit ASCII character.\n" "Use the header editor to fix your file. Look at the manual for the details.", i + 1); free(edf_hdr); free(edfhdr); return(NULL); } } strncpy(edfhdr->patient, edf_hdr + 8, 80); edfhdr->patient[80] = 0; /********************* RECORDING *********************************************/ strncpy(scratchpad, edf_hdr + 88, 80); scratchpad[80] = 0; for(i=0; i<80; i++) { if((((unsigned char *)scratchpad)[i]<32)||(((unsigned char *)scratchpad)[i]>126)) { sprintf(txt_string, "Error, %ith character of local recording identification field is not a valid 7-bit ASCII character.\n" "Use the header editor to fix your file. Look at the manual for the details.", i + 1); free(edf_hdr); free(edfhdr); return(NULL); } } strncpy(edfhdr->recording, edf_hdr + 88, 80); edfhdr->recording[80] = 0; /********************* STARTDATE *********************************************/ strncpy(scratchpad, edf_hdr + 168, 8); scratchpad[8] = 0; for(i=0; i<8; i++) { if((scratchpad[i]<32)||(scratchpad[i]>126)) { sprintf(txt_string, "Error, %ith character of startdate field is not a valid 7-bit ASCII character.", i + 1); free(edf_hdr); free(edfhdr); return(NULL); } } error = 0; if((edf_hdr[170]!='.')||(edf_hdr[173]!='.')) { sprintf(txt_string, "Error, separator character of startdate is not a dot.\n" "You can fix this problem with the header editor, check the manual for details."); free(edf_hdr); free(edfhdr); return(NULL); } if((edf_hdr[168]<48)||(edf_hdr[168]>57)) error = 1; if((edf_hdr[169]<48)||(edf_hdr[169]>57)) error = 1; if((edf_hdr[171]<48)||(edf_hdr[171]>57)) error = 1; if((edf_hdr[172]<48)||(edf_hdr[172]>57)) error = 1; if((edf_hdr[174]<48)||(edf_hdr[174]>57)) error = 1; if((edf_hdr[175]<48)||(edf_hdr[175]>57)) error = 1; strncpy(scratchpad, edf_hdr + 168, 8); if(error) { scratchpad[8] = 0; sprintf(txt_string, "Error, startdate of recording is invalid: \"%s\",\n" "expected \"dd.mm.yy\"", scratchpad); free(edf_hdr); return(NULL); } scratchpad[2] = 0; scratchpad[5] = 0; scratchpad[8] = 0; if((atoi(scratchpad)<1)||(atoi(scratchpad)>31)) { strncpy(scratchpad, edf_hdr + 168, 8); scratchpad[8] = 0; sprintf(txt_string, "Error, startdate of recording is invalid: \"%s\",\n" "expected \"dd.mm.yy\" where \"dd\" should be more than 00 and less than 32", scratchpad); free(edf_hdr); return(NULL); } if((atoi(scratchpad+3)<1)||(atoi(scratchpad+3)>12)) { strncpy(scratchpad, edf_hdr + 168, 8); scratchpad[8] = 0; sprintf(txt_string, "Error, startdate of recording is invalid: \"%s\",\n" "expected \"dd.mm.yy\" where \"mm\" should be more than 00 and less than 13", scratchpad); free(edf_hdr); free(edfhdr); return(NULL); } date_time.day = atoi(scratchpad); date_time.month = atoi(scratchpad + 3); date_time.year = atoi(scratchpad + 6); if(date_time.year>84) { date_time.year += 1900; } else { date_time.year += 2000; } /********************* STARTTIME *********************************************/ strncpy(scratchpad, edf_hdr + 176, 8); scratchpad[8] = 0; for(i=0; i<8; i++) { if((scratchpad[i]<32)||(scratchpad[i]>126)) { sprintf(txt_string, "Error, %ith character of starttime field is not a valid 7-bit ASCII character.", i + 1); free(edf_hdr); free(edfhdr); return(NULL); } } error = 0; if((edf_hdr[178]!='.')||(edf_hdr[181]!='.')) { sprintf(txt_string, "Error, separator character of starttime is not a dot.\n" "You can fix this problem with the header editor, check the manual for details."); free(edf_hdr); free(edfhdr); return(NULL); } if((edf_hdr[176]<48)||(edf_hdr[176]>57)) error = 1; if((edf_hdr[177]<48)||(edf_hdr[177]>57)) error = 1; if((edf_hdr[179]<48)||(edf_hdr[179]>57)) error = 1; if((edf_hdr[180]<48)||(edf_hdr[180]>57)) error = 1; if((edf_hdr[182]<48)||(edf_hdr[182]>57)) error = 1; if((edf_hdr[183]<48)||(edf_hdr[183]>57)) error = 1; strncpy(scratchpad, edf_hdr + 176, 8); if(error) { strncpy(scratchpad, edf_hdr + 176, 8); scratchpad[8] = 0; sprintf(txt_string, "Error, starttime of recording is invalid: \"%s\",\n" "expected \"hh.mm.ss\"", scratchpad); free(edf_hdr); free(edfhdr); return(NULL); } scratchpad[2] = 0; scratchpad[5] = 0; scratchpad[8] = 0; if(atoi(scratchpad)>23) { strncpy(scratchpad, edf_hdr + 176, 8); scratchpad[8] = 0; sprintf(txt_string, "Error, starttime of recording is invalid: \"%s\",\n" "expected \"hh.mm.ss\" where \"hh\" should be less than 24", scratchpad); free(edf_hdr); free(edfhdr); return(NULL); } if(atoi(scratchpad+3)>59) { strncpy(scratchpad, edf_hdr + 176, 8); scratchpad[8] = 0; sprintf(txt_string, "Error, starttime of recording is invalid: \"%s\",\n" "expected \"hh.mm.ss\" where \"mm\" should be less than 60", scratchpad); free(edf_hdr); free(edfhdr); return(NULL); } if(atoi(scratchpad+6)>59) { strncpy(scratchpad, edf_hdr + 176, 8); scratchpad[8] = 0; sprintf(txt_string, "Error, starttime of recording is invalid: \"%s\",\n" "expected \"hh.mm.ss\" where \"ss\" should be less than 60", scratchpad); free(edf_hdr); free(edfhdr); return(NULL); } date_time.hour = atoi(scratchpad); date_time.minute = atoi(scratchpad + 3); date_time.second = atoi(scratchpad + 6); date_time_to_utc(&edfhdr->utc_starttime, date_time); edfhdr->l_starttime = 3600 * atoi(scratchpad); edfhdr->l_starttime += 60 * atoi(scratchpad + 3); edfhdr->l_starttime += atoi(scratchpad + 6); edfhdr->l_starttime *= TIME_DIMENSION; /***************** NUMBER OF SIGNALS IN HEADER *******************************/ strncpy(scratchpad, edf_hdr + 252, 4); scratchpad[4] = 0; for(i=0; i<4; i++) { if((scratchpad[i]<32)||(scratchpad[i]>126)) { sprintf(txt_string, "Error, %ith character of number of signals field is not a valid 7-bit ASCII character.", i + 1); free(edf_hdr); free(edfhdr); return(NULL); } } if(is_integer_number(scratchpad)) { sprintf(txt_string, "Error, number of signals field is invalid: \"%s\".", scratchpad); free(edf_hdr); free(edfhdr); return(NULL); } edfhdr->edfsignals = atoi(scratchpad); if(edfhdr->edfsignals<1) { sprintf(txt_string, "Error, number of signals is %i, expected >0.", edfhdr->edfsignals); free(edf_hdr); free(edfhdr); return(NULL); } if(edfhdr->edfsignals>MAXSIGNALS) { sprintf(txt_string, "Error, number of signals in file is %i, can not support more than %i signals.", edfhdr->edfsignals, MAXSIGNALS); free(edf_hdr); free(edfhdr); return(NULL); } /***************** NUMBER OF BYTES IN HEADER *******************************/ strncpy(scratchpad, edf_hdr + 184, 8); scratchpad[8] = 0; for(i=0; i<8; i++) { if((scratchpad[i]<32)||(scratchpad[i]>126)) { sprintf(txt_string, "Error, %ith character of number of bytes in header field is not a valid 7-bit ASCII character.", i + 1); free(edf_hdr); free(edfhdr); return(NULL); } } if(is_integer_number(scratchpad)) { sprintf(txt_string, "Error, number of bytes in header field is invalid: \"%s\".", scratchpad); free(edf_hdr); free(edfhdr); return(NULL); } n = atoi(scratchpad); if((edfhdr->edfsignals * 256 + 256)!=n) { sprintf(txt_string, "Error, number of bytes in header does not match: %i,\n" "expected %i signals * 256 + 256 = %i bytes.", n, edfhdr->edfsignals, edfhdr->edfsignals * 256 + 256); free(edf_hdr); free(edfhdr); return(NULL); } /********************* RESERVED FIELD *************************************/ edfhdr->edfplus = 0; edfhdr->discontinuous = 0; strncpy(scratchpad, edf_hdr + 192, 44); scratchpad[44] = 0; for(i=0; i<44; i++) { if((scratchpad[i]<32)||(scratchpad[i]>126)) { sprintf(txt_string, "Error, %ith character of reserved field is not a valid 7-bit ASCII character.", i + 1); free(edf_hdr); free(edfhdr); return(NULL); } } if(edfhdr->edf) { if(!strncmp(scratchpad, "EDF+C", 5)) { edfhdr->edfplus = 1; } if(!strncmp(scratchpad, "EDF+D", 5)) { edfhdr->edfplus = 1; edfhdr->discontinuous = 1; } } if(edfhdr->bdf) { if(!strncmp(scratchpad, "BDF+C", 5)) { edfhdr->bdfplus = 1; } if(!strncmp(scratchpad, "BDF+D", 5)) { edfhdr->bdfplus = 1; edfhdr->discontinuous = 1; } } strncpy(edfhdr->reserved, edf_hdr + 192, 44); edfhdr->reserved[44] = 0; /********************* NUMBER OF DATARECORDS *************************************/ strncpy(scratchpad, edf_hdr + 236, 8); scratchpad[8] = 0; for(i=0; i<8; i++) { if((scratchpad[i]<32)||(scratchpad[i]>126)) { sprintf(txt_string, "Error, %ith character of number of datarecords field is not a valid ASCII character.", i + 1); free(edf_hdr); free(edfhdr); return(NULL); } } if(is_integer_number(scratchpad)) { sprintf(txt_string, "Error, number of datarecords field is invalid: \"%s\".\n" "You can fix this problem with the header editor, check the manual for details.", scratchpad); free(edf_hdr); free(edfhdr); return(NULL); } edfhdr->datarecords = atoi(scratchpad); if(live_stream == 0) { if(edfhdr->datarecords<1) { #ifdef Q_WS_WIN sprintf(txt_string, "Error, number of datarecords is %I64d, expected >0.\n" "You can fix this problem with the header editor, check the manual for details.", edfhdr->datarecords); #else sprintf(txt_string, "Error, number of datarecords is %lli, expected >0.\n" "You can fix this problem with the header editor, check the manual for details.", edfhdr->datarecords); #endif free(edf_hdr); free(edfhdr); return(NULL); } } /********************* DATARECORD DURATION *************************************/ strncpy(scratchpad, edf_hdr + 244, 8); scratchpad[8] = 0; for(i=0; i<8; i++) { if((scratchpad[i]<32)||(scratchpad[i]>126)) { sprintf(txt_string, "Error, %ith character of recordduration field is not a valid 7-bit ASCII character.", i + 1); free(edf_hdr); free(edfhdr); return(NULL); } } if(is_number(scratchpad)) { sprintf(txt_string, "Error, record duration field is invalid: \"%s\".", scratchpad); free(edf_hdr); free(edfhdr); return(NULL); } edfhdr->data_record_duration = atof(scratchpad); if(edfhdr->data_record_duration<-0.000001) { sprintf(txt_string, "Error, record duration is invalid: \"%s\", should be >=0", scratchpad); free(edf_hdr); free(edfhdr); return(NULL); } edfhdr->long_data_record_duration = get_long_duration(scratchpad); free(edf_hdr); /********************* START WITH THE SIGNALS IN THE HEADER *********************/ edf_hdr = (char *)calloc(1, (edfhdr->edfsignals + 1) * 256); if(edf_hdr==NULL) { sprintf(txt_string, "Memory allocation error. (edf_hdr takes %i bytes)", (edfhdr->edfsignals + 1) * 256); free(edfhdr); return(NULL); } rewind(inputfile); if(fread(edf_hdr, (edfhdr->edfsignals + 1) * 256, 1, inputfile)!=1) { sprintf(txt_string, "Error, reading %i bytes from file", (edfhdr->edfsignals + 1) * 256); free(edf_hdr); free(edfhdr); return(NULL); } edfhdr->edfparam = (struct edfparamblock *)calloc(1, sizeof(struct edfparamblock[edfhdr->edfsignals])); if(edfhdr->edfparam==NULL) { sprintf(txt_string, "Memory allocation error! (edfparam)"); free(edf_hdr); free(edfhdr); return(NULL); } /**************************** LABELS *************************************/ edfhdr->nr_annot_chns = 0; for(i=0; iedfsignals; i++) { strncpy(scratchpad, edf_hdr + 256 + (i * 16), 16); for(j=0; j<16; j++) { if((scratchpad[j]<32)||(scratchpad[j]>126)) { sprintf(txt_string, "Error, %ith character of label field of signal %i is not a valid 7-bit ASCII character.\n" "Use the header editor to fix your file. Look at the manual for the details.", j + 1, i + 1); free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } if(edfhdr->edfplus) { if(!strncmp(scratchpad, "EDF Annotations ", 16)) { edfhdr->annot_ch[edfhdr->nr_annot_chns] = i; edfhdr->nr_annot_chns++; edfhdr->edfparam[i].annotation = 1; } } if(edfhdr->bdfplus) { if(!strncmp(scratchpad, "BDF Annotations ", 16)) { edfhdr->annot_ch[edfhdr->nr_annot_chns] = i; edfhdr->nr_annot_chns++; edfhdr->edfparam[i].annotation = 1; } } strncpy(edfhdr->edfparam[i].label, edf_hdr + 256 + (i * 16), 16); edfhdr->edfparam[i].label[16] = 0; } if(edfhdr->edfplus&&(!edfhdr->nr_annot_chns)) { sprintf(txt_string, "Error, file is marked as EDF+ but it has no annotations-signal."); free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } if(edfhdr->bdfplus&&(!edfhdr->nr_annot_chns)) { sprintf(txt_string, "Error, file is marked as BDF+ but it has no annotations-signal."); free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } if((edfhdr->edfsignals!=edfhdr->nr_annot_chns)||((!edfhdr->edfplus)&&(!edfhdr->bdfplus))) { if(edfhdr->data_record_duration<0.000001) { sprintf(txt_string, "Error, record duration is invalid, should be >0"); free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } /**************************** TRANSDUCER TYPES *************************************/ for(i=0; iedfsignals; i++) { strncpy(scratchpad, edf_hdr + 256 + (edfhdr->edfsignals * 16) + (i * 80), 80); for(j=0; j<80; j++) { if((scratchpad[j]<32)||(scratchpad[j]>126)) { sprintf(txt_string, "Error, %ith character of transducer type field of signal %i is not a valid 7-bit ASCII character.\n" "Use the header editor to fix your file. Look at the manual for the details.", j + 1, i + 1); free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } strncpy(edfhdr->edfparam[i].transducer, edf_hdr + 256 + (edfhdr->edfsignals * 16) + (i * 80), 80); edfhdr->edfparam[i].transducer[80] = 0; if(edfhdr->edfplus) { if(edfhdr->edfparam[i].annotation) { for(j=0; j<80; j++) { if(edfhdr->edfparam[i].transducer[j]!=' ') { sprintf(txt_string, "Error, transducer type field of EDF annotationchannel must be empty.\n" "Use the header editor to fix your file. Look at the manual for the details."); free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } } } if(edfhdr->bdfplus) { if(edfhdr->edfparam[i].annotation) { for(j=0; j<80; j++) { if(edfhdr->edfparam[i].transducer[j]!=' ') { sprintf(txt_string, "Error, transducer type field of BDF annotationchannel must be empty." "Use the header editor to fix your file. Look at the manual for the details."); free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } } } } /**************************** PHYSICAL DIMENSIONS *************************************/ for(i=0; iedfsignals; i++) { strncpy(scratchpad, edf_hdr + 256 + (edfhdr->edfsignals * 96) + (i * 8), 8); for(j=0; j<8; j++) { if((scratchpad[j]<32)||(scratchpad[j]>126)) { sprintf(txt_string, "Error, %ith character of physical dimension field of signal %i is not a valid 7-bit ASCII character.\n" "Use the header editor to fix your file. Look at the manual for the details.", j + 1, i + 1); free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } strncpy(edfhdr->edfparam[i].physdimension, edf_hdr + 256 + (edfhdr->edfsignals * 96) + (i * 8), 8); edfhdr->edfparam[i].physdimension[8] = 0; } /**************************** PHYSICAL MINIMUMS *************************************/ for(i=0; iedfsignals; i++) { strncpy(scratchpad, edf_hdr + 256 + (edfhdr->edfsignals * 104) + (i * 8), 8); scratchpad[8] = 0; for(j=0; j<8; j++) { if((scratchpad[j]<32)||(scratchpad[j]>126)) { sprintf(txt_string, "Error, %ith character of physical minimum field of signal %i is not a valid 7-bit ASCII character.", j + 1, i + 1); free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } if(is_number(scratchpad)) { sprintf(txt_string, "Error, physical minimum field of signal %i is invalid: \"%s\".", i + 1, scratchpad); free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } edfhdr->edfparam[i].phys_min = atof(scratchpad); } /**************************** PHYSICAL MAXIMUMS *************************************/ for(i=0; iedfsignals; i++) { strncpy(scratchpad, edf_hdr + 256 + (edfhdr->edfsignals * 112) + (i * 8), 8); scratchpad[8] = 0; for(j=0; j<8; j++) { if((scratchpad[j]<32)||(scratchpad[j]>126)) { sprintf(txt_string, "Error, %ith character of physical maximum field of signal %i is not a valid 7-bit ASCII character.", j + 1, i + 1); free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } if(is_number(scratchpad)) { sprintf(txt_string, "Error, physical maximum field of signal %i is invalid: \"%s\".", i + 1, scratchpad); free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } edfhdr->edfparam[i].phys_max = atof(scratchpad); if(edfhdr->edfparam[i].phys_max==edfhdr->edfparam[i].phys_min) { sprintf(txt_string, "Error, physical maximum of signal %i is equal to physical minimum", i + 1); free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } /**************************** DIGITAL MINIMUMS *************************************/ for(i=0; iedfsignals; i++) { strncpy(scratchpad, edf_hdr + 256 + (edfhdr->edfsignals * 120) + (i * 8), 8); scratchpad[8] = 0; for(j=0; j<8; j++) { if((scratchpad[j]<32)||(scratchpad[j]>126)) { sprintf(txt_string, "Error, %ith character of digital minimum field of signal %i is not a valid 7-bit ASCII character.", j + 1, i + 1); free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } if(is_integer_number(scratchpad)) { sprintf(txt_string, "Error, digital minimum field of signal %i is invalid: \"%s\".\n" "Use the header editor to fix your file. Look at the manual for the details.", i + 1, scratchpad); free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } n = atoi(scratchpad); if(edfhdr->edfplus) { if(edfhdr->edfparam[i].annotation) { if(n!=-32768) { sprintf(txt_string, "Error, digital minimum of signal %i is wrong: %i," "\ndigital minimum of an EDF Annotations signal should be -32768\n" "Use the header editor to fix your file. Look at the manual for the details.", i + 1, n); free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } } if(edfhdr->bdfplus) { if(edfhdr->edfparam[i].annotation) { if(n!=-8388608) { sprintf(txt_string, "Error, digital minimum of signal %i is wrong: %i," "\ndigital minimum of a BDF Annotations signal should be -8388608\n" "Use the header editor to fix your file. Look at the manual for the details.", i + 1, n); free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } } if(edfhdr->edf) { if((n>32767)||(n<-32768)) { sprintf(txt_string, "Error, digital minimum of signal %i is out of range: %i,\nshould be in the range -32768 to 32767", i + 1, n); free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } if(edfhdr->bdf) { if((n>8388607)||(n<-8388608)) { sprintf(txt_string, "Error, digital minimum of signal %i is out of range: %i,\nshould be in the range -8388608 to 8388607", i + 1, n); free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } edfhdr->edfparam[i].dig_min = n; } /**************************** DIGITAL MAXIMUMS *************************************/ for(i=0; iedfsignals; i++) { strncpy(scratchpad, edf_hdr + 256 + (edfhdr->edfsignals * 128) + (i * 8), 8); scratchpad[8] = 0; for(j=0; j<8; j++) { if((scratchpad[j]<32)||(scratchpad[j]>126)) { sprintf(txt_string, "Error, %ith character of digital maximum field of signal %i is not a valid 7-bit ASCII character.", j + 1, i + 1); free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } if(is_integer_number(scratchpad)) { sprintf(txt_string, "Error, digital maximum field of signal %i is invalid: \"%s\".\n" "Use the header editor to fix your file. Look at the manual for the details.", i + 1, scratchpad); free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } n = atoi(scratchpad); if(edfhdr->edfplus) { if(edfhdr->edfparam[i].annotation) { if(n!=32767) { sprintf(txt_string, "Error, digital maximum of signal %i is wrong: %i," "\ndigital maximum of an EDF Annotations signal should be 32767\n" "Use the header editor to fix your file. Look at the manual for the details.", i + 1, n); free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } } if(edfhdr->bdfplus) { if(edfhdr->edfparam[i].annotation) { if(n!=8388607) { sprintf(txt_string, "Error, digital maximum of signal %i is wrong: %i," "\ndigital maximum of a BDF Annotations signal should be 8388607\n" "Use the header editor to fix your file. Look at the manual for the details.", i + 1, n); free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } } if(edfhdr->edf) { if((n>32767)||(n<-32768)) { sprintf(txt_string, "Error, digital maximum of signal %i is out of range: %i,\nshould be in the range -32768 to 32767", i + 1, n); free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } else { if((n>8388607)||(n<-8388608)) { sprintf(txt_string, "Error, digital maximum of signal %i is out of range: %i,\nshould be in the range -8388608 to 8388607", i + 1, n); free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } edfhdr->edfparam[i].dig_max = n; if(edfhdr->edfparam[i].dig_max<(edfhdr->edfparam[i].dig_min + 1)) { sprintf(txt_string, "Error, digital maximum of signal %i is less than or equal to digital minimum", i + 1); free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } /**************************** PREFILTER FIELDS *************************************/ for(i=0; iedfsignals; i++) { strncpy(scratchpad, edf_hdr + 256 + (edfhdr->edfsignals * 136) + (i * 80), 80); for(j=0; j<80; j++) { if((scratchpad[j]<32)||(scratchpad[j]>126)) { sprintf(txt_string, "Error, %ith character of prefilter field of signal %i is not a valid 7-bit ASCII character.\n" "Use the header editor to fix your file. Look at the manual for the details.", j + 1, i + 1); free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } strncpy(edfhdr->edfparam[i].prefilter, edf_hdr + 256 + (edfhdr->edfsignals * 136) + (i * 80), 80); edfhdr->edfparam[i].prefilter[80] = 0; if(edfhdr->edfplus) { if(edfhdr->edfparam[i].annotation) { for(j=0; j<80; j++) { if(edfhdr->edfparam[i].prefilter[j]!=' ') { sprintf(txt_string, "Error, prefilter field of EDF annotationchannel must be empty.\n" "Use the header editor to fix your file. Look at the manual for the details."); free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } } } if(edfhdr->bdfplus) { if(edfhdr->edfparam[i].annotation) { for(j=0; j<80; j++) { if(edfhdr->edfparam[i].prefilter[j]!=' ') { sprintf(txt_string, "Error, prefilter field of BDF annotationchannel must be empty.\n" "Use the header editor to fix your file. Look at the manual for the details."); free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } } } } /*********************** NR OF SAMPLES IN EACH DATARECORD ********************/ edfhdr->recordsize = 0; for(i=0; iedfsignals; i++) { strncpy(scratchpad, edf_hdr + 256 + (edfhdr->edfsignals * 216) + (i * 8), 8); scratchpad[8] = 0; for(j=0; j<8; j++) { if((scratchpad[j]<32)||(scratchpad[j]>126)) { sprintf(txt_string, "Error, %ith character of number of samples field of signal %i is not a valid 7-bit ASCII character.", j + 1, i + 1); free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } if(is_integer_number(scratchpad)) { sprintf(txt_string, "Error, number of samples in datarecord field of signal %i is invalid: \"%s\".", i + 1, scratchpad); free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } n = atoi(scratchpad); if(n<1) { sprintf(txt_string, "Error, number of samples in datarecord of signal %i is out of range: %i,\nshould be >0", i + 1, n); free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } edfhdr->edfparam[i].smp_per_record = n; edfhdr->recordsize += n; } if(edfhdr->bdf) { edfhdr->recordsize *= 3; if(edfhdr->recordsize > 15728640) { sprintf(txt_string, "Error, the datarecordsize is %i bytes. The datarecordsize should not exceed 15 MB.", edfhdr->recordsize); free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } else { edfhdr->recordsize *= 2; if(edfhdr->recordsize > 10485760) { sprintf(txt_string, "Error, the datarecordsize is %i bytes. The datarecordsize should not exceed 10 MB.", edfhdr->recordsize); free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } /**************************** RESERVED FIELDS *************************************/ for(i=0; iedfsignals; i++) { strncpy(scratchpad, edf_hdr + 256 + (edfhdr->edfsignals * 224) + (i * 32), 32); for(j=0; j<32; j++) { if((scratchpad[j]<32)||(scratchpad[j]>126)) { sprintf(txt_string, "Error, %ith character of reserved field of signal %i is not a valid 7-bit ASCII character.", j + 1, i + 1); free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } strncpy(edfhdr->edfparam[i].reserved, edf_hdr + 256 + (edfhdr->edfsignals * 224) + (i * 32), 32); edfhdr->edfparam[i].reserved[32] = 0; } /********************* EDF+ PATIENTNAME *********************************************/ if(edfhdr->edfplus || edfhdr->bdfplus) { error = 0; dotposition = 0; strncpy(scratchpad, edf_hdr + 8, 80); scratchpad[80] = 0; for(i=0; i<80; i++) { if(scratchpad[i]==' ') { dotposition = i; break; } } dotposition++; if((dotposition>73)||(dotposition<2)) error = 1; if(scratchpad[dotposition + 2]!='X') { if(dotposition>65) error = 1; } if((scratchpad[dotposition]!='M')&&(scratchpad[dotposition]!='F')&&(scratchpad[dotposition]!='X')) error = 1; dotposition++; if(scratchpad[dotposition]!=' ') error = 1; if(scratchpad[dotposition + 1]=='X') { if(scratchpad[dotposition + 2]!=' ') error = 1; if(scratchpad[dotposition + 3]==' ') error = 1; } else { if(scratchpad[dotposition + 12]!=' ') error = 1; if(scratchpad[dotposition + 13]==' ') error = 1; dotposition++; strncpy(scratchpad2, scratchpad + dotposition, 11); scratchpad2[11] = 0; if((scratchpad2[2]!='-')||(scratchpad2[6]!='-')) error = 1; scratchpad2[2] = 0; scratchpad2[6] = 0; if((scratchpad2[0]<48)||(scratchpad2[0]>57)) error = 1; if((scratchpad2[1]<48)||(scratchpad2[1]>57)) error = 1; if((scratchpad2[7]<48)||(scratchpad2[7]>57)) error = 1; if((scratchpad2[8]<48)||(scratchpad2[8]>57)) error = 1; if((scratchpad2[9]<48)||(scratchpad2[9]>57)) error = 1; if((scratchpad2[10]<48)||(scratchpad2[10]>57)) error = 1; if((atoi(scratchpad2)<1)||(atoi(scratchpad2)>31)) error = 1; if(strcmp(scratchpad2 + 3, "JAN")) if(strcmp(scratchpad2 + 3, "FEB")) if(strcmp(scratchpad2 + 3, "MAR")) if(strcmp(scratchpad2 + 3, "APR")) if(strcmp(scratchpad2 + 3, "MAY")) if(strcmp(scratchpad2 + 3, "JUN")) if(strcmp(scratchpad2 + 3, "JUL")) if(strcmp(scratchpad2 + 3, "AUG")) if(strcmp(scratchpad2 + 3, "SEP")) if(strcmp(scratchpad2 + 3, "OCT")) if(strcmp(scratchpad2 + 3, "NOV")) if(strcmp(scratchpad2 + 3, "DEC")) error = 1; } if(error) { if(edfhdr->edfplus) { sprintf(txt_string, "Error, file is marked as EDF+ but local patient identification field does not\ncomply to the EDF+ standard:\n" "\"%.80s\"", edf_hdr+8); } if(edfhdr->bdfplus) { sprintf(txt_string, "Error, file is marked as BDF+ but local patient identification field does not\ncomply to the BDF+ standard:\n" "\"%.80s\"", edf_hdr+8); } free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } p = 0; if(edfhdr->patient[p]=='X') { edfhdr->plus_patientcode[0] = 0; p += 2; } else { for(i=0; i<(80-p); i++) { if(edfhdr->patient[i+p]==' ') { break; } edfhdr->plus_patientcode[i] = edfhdr->patient[i+p]; if(edfhdr->plus_patientcode[i]=='_') edfhdr->plus_patientcode[i] = ' '; } edfhdr->plus_patientcode[i] = 0; p += i + 1; } if(edfhdr->patient[p]=='M') { strcpy(edfhdr->plus_gender, "Male"); } if(edfhdr->patient[p]=='F') { strcpy(edfhdr->plus_gender, "Female"); } if(edfhdr->patient[p]=='X') { edfhdr->plus_gender[0] = 0; } for(i=0; i<(80-p);i++) { if(edfhdr->patient[i+p]==' ') { break; } } p += i + 1; if(edfhdr->patient[p]=='X') { edfhdr->plus_birthdate[0] = 0; p += 2; } else { for(i=0; i<(80-p); i++) { if(edfhdr->patient[i+p]==' ') { break; } edfhdr->plus_birthdate[i] = edfhdr->patient[i+p]; } edfhdr->plus_birthdate[2] = ' '; edfhdr->plus_birthdate[3] += 32; edfhdr->plus_birthdate[4] += 32; edfhdr->plus_birthdate[5] += 32; edfhdr->plus_birthdate[6] = ' '; edfhdr->plus_birthdate[11] = 0; p += i + 1; } for(i=0; i<(80-p);i++) { if(edfhdr->patient[i+p]==' ') { break; } edfhdr->plus_patient_name[i] = edfhdr->patient[i+p]; if(edfhdr->plus_patient_name[i]=='_') edfhdr->plus_patient_name[i] = ' '; } edfhdr->plus_patient_name[i] = 0; p += i + 1; for(i=0; i<(80-p);i++) { edfhdr->plus_patient_additional[i] = edfhdr->patient[i+p]; } edfhdr->plus_patient_additional[i] = 0; p += i + 1; } /********************* EDF+ RECORDINGFIELD *********************************************/ if(edfhdr->edfplus || edfhdr->bdfplus) { error = 0; strncpy(scratchpad, edf_hdr + 88, 80); scratchpad[80] = 0; if(strncmp(scratchpad, "Startdate ", 10)) error = 1; if(scratchpad[10]=='X') { if(scratchpad[11]!=' ') error = 1; if(scratchpad[12]==' ') error = 1; p = 12; } else { if(scratchpad[21]!=' ') error = 1; if(scratchpad[22]==' ') error = 1; p = 22; strncpy(scratchpad2, scratchpad + 10, 11); scratchpad2[11] = 0; if((scratchpad2[2]!='-')||(scratchpad2[6]!='-')) error = 1; scratchpad2[2] = 0; scratchpad2[6] = 0; if((scratchpad2[0]<48)||(scratchpad2[0]>57)) error = 1; if((scratchpad2[1]<48)||(scratchpad2[1]>57)) error = 1; if((scratchpad2[7]<48)||(scratchpad2[7]>57)) error = 1; if((scratchpad2[8]<48)||(scratchpad2[8]>57)) error = 1; if((scratchpad2[9]<48)||(scratchpad2[9]>57)) error = 1; if((scratchpad2[10]<48)||(scratchpad2[10]>57)) error = 1; if((atoi(scratchpad2)<1)||(atoi(scratchpad2)>31)) error = 1; r = 0; if(!strcmp(scratchpad2 + 3, "JAN")) r = 1; else if(!strcmp(scratchpad2 + 3, "FEB")) r = 2; else if(!strcmp(scratchpad2 + 3, "MAR")) r = 3; else if(!strcmp(scratchpad2 + 3, "APR")) r = 4; else if(!strcmp(scratchpad2 + 3, "MAY")) r = 5; else if(!strcmp(scratchpad2 + 3, "JUN")) r = 6; else if(!strcmp(scratchpad2 + 3, "JUL")) r = 7; else if(!strcmp(scratchpad2 + 3, "AUG")) r = 8; else if(!strcmp(scratchpad2 + 3, "SEP")) r = 9; else if(!strcmp(scratchpad2 + 3, "OCT")) r = 10; else if(!strcmp(scratchpad2 + 3, "NOV")) r = 11; else if(!strcmp(scratchpad2 + 3, "DEC")) r = 12; else error = 1; } n = 0; for(i=p; i<80; i++) { if(i>78) { error = 1; break; } if(scratchpad[i]==' ') { n++; if(scratchpad[i + 1]==' ') { error = 1; break; } } if(n>1) break; } if(error) { if(edfhdr->edfplus) { sprintf(txt_string, "Error, file is marked as EDF+ but recording field does not comply to the\nEDF+ standard:\n" "\"%.80s\"", edf_hdr+88); } if(edfhdr->bdfplus) { sprintf(txt_string, "Error, file is marked as BDF+ but recording field does not comply to the\nBDF+ standard:\n" "\"%.80s\"", edf_hdr+88); } free(edf_hdr); free(edfhdr->edfparam); return(NULL); } if(edf_hdr[98]!='X') { error = 0; strncpy(scratchpad, edf_hdr + 168, 8); scratchpad[2] = 0; scratchpad[5] = 0; scratchpad[8] = 0; if(atoi(scratchpad)!=atoi(scratchpad2)) error = 1; if(atoi(scratchpad+3)!=r) error = 1; if(atoi(scratchpad+6)!=atoi(scratchpad2+9)) error = 1; if(error) { if(edfhdr->edfplus) { sprintf(txt_string, "Error, file is marked as EDF+ but startdate field does not match with startdate in\nrecordfield:\n" "\"%.8s\" <-> \"%.11s\".", edf_hdr+168, edf_hdr+98); } if(edfhdr->bdfplus) { sprintf(txt_string, "Error, file is marked as BDF+ but startdate field does not match with startdate in\nrecordfield:\n" "\"%.8s\" <-> \"%.11s\".", edf_hdr+168, edf_hdr+98); } free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } date_time.year = atoi(scratchpad2 + 7); if(date_time.year<1970) { sprintf(txt_string, "Error, recording startdate is older than 1970."); free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } date_time_to_utc(&edfhdr->utc_starttime, date_time); } p = 10; for(i=0; i<(80-p); i++) { if(edfhdr->recording[i+p]==' ') { break; } edfhdr->plus_startdate[i] = edfhdr->recording[i+p]; } edfhdr->plus_startdate[2] = ' '; edfhdr->plus_startdate[3] += 32; edfhdr->plus_startdate[4] += 32; edfhdr->plus_startdate[5] += 32; edfhdr->plus_startdate[6] = ' '; edfhdr->plus_startdate[11] = 0; p += i + 1; if(edfhdr->recording[p]=='X') { edfhdr->plus_admincode[0] = 0; p += 2; } else { for(i=0; i<(80-p); i++) { if(edfhdr->recording[i+p]==' ') { break; } edfhdr->plus_admincode[i] = edfhdr->recording[i+p]; if(edfhdr->plus_admincode[i]=='_') edfhdr->plus_admincode[i] = ' '; } edfhdr->plus_admincode[i] = 0; p += i + 1; } if(edfhdr->recording[p]=='X') { edfhdr->plus_technician[0] = 0; p += 2; } else { for(i=0; i<(80-p); i++) { if(edfhdr->recording[i+p]==' ') { break; } edfhdr->plus_technician[i] = edfhdr->recording[i+p]; if(edfhdr->plus_technician[i]=='_') edfhdr->plus_technician[i] = ' '; } edfhdr->plus_technician[i] = 0; p += i + 1; } if(edfhdr->recording[p]=='X') { edfhdr->plus_equipment[0] = 0; p += 2; } else { for(i=0; i<(80-p); i++) { if(edfhdr->recording[i+p]==' ') { break; } edfhdr->plus_equipment[i] = edfhdr->recording[i+p]; if(edfhdr->plus_equipment[i]=='_') edfhdr->plus_equipment[i] = ' '; } edfhdr->plus_equipment[i] = 0; p += i + 1; } for(i=0; i<(80-p);i++) { edfhdr->plus_recording_additional[i] = edfhdr->recording[i+p]; } edfhdr->plus_recording_additional[i] = 0; p += i + 1; } /********************* FILESIZE *********************************************/ edfhdr->hdrsize = edfhdr->edfsignals * 256 + 256; if(live_stream) { fseeko(inputfile, 0LL, SEEK_END); edfhdr->datarecords = ftello(inputfile); edfhdr->datarecords -= (long long)edfhdr->hdrsize; edfhdr->datarecords /= (long long)edfhdr->recordsize; } else { l_tmp = edfhdr->recordsize; l_tmp *= edfhdr->datarecords; l_tmp += (edfhdr->edfsignals * 256 + 256); fseeko(inputfile, 0LL, SEEK_END); l_tmp2 = ftello(inputfile); if(l_tmp != l_tmp2) { #ifdef Q_WS_WIN sprintf(txt_string, "Error, filesize does not match with the calculated filesize based on the parameters\n" "in the header. Filesize is %I64i and filesize according to header is %I64i.\n" "You can fix this problem with the header editor, check the manual for details.", l_tmp2, l_tmp); #else sprintf(txt_string, "Error, filesize does not match with the calculated filesize based on the parameters\n" "in the header. Filesize is %lli and filesize according to header is %lli.\n" "You can fix this problem with the header editor, check the manual for details.", l_tmp2, l_tmp); #endif free(edf_hdr); free(edfhdr->edfparam); free(edfhdr); return(NULL); } } n = 0; for(i=0; iedfsignals; i++) { edfhdr->edfparam[i].buf_offset = n; if(edfhdr->bdf) n += edfhdr->edfparam[i].smp_per_record * 3; else n += edfhdr->edfparam[i].smp_per_record * 2; edfhdr->edfparam[i].bitvalue = (edfhdr->edfparam[i].phys_max - edfhdr->edfparam[i].phys_min) / (edfhdr->edfparam[i].dig_max - edfhdr->edfparam[i].dig_min); edfhdr->edfparam[i].offset = edfhdr->edfparam[i].phys_max / edfhdr->edfparam[i].bitvalue - edfhdr->edfparam[i].dig_max; } txt_string[0] = 0; free(edf_hdr); return(edfhdr); } int EDFfileCheck::is_integer_number(char *str) { int i=0, l, hasspace = 0, hassign=0, digit=0; l = strlen(str); if(!l) return(1); if((str[0]=='+')||(str[0]=='-')) { hassign++; i++; } for(; i57)) { return(1); } else { if(hasspace) { return(1); } digit++; } } } if(digit) return(0); else return(1); } int EDFfileCheck::is_number(char *str) { int i=0, l, hasspace = 0, hassign=0, digit=0, hasdot=0, hasexp=0; l = strlen(str); if(!l) return(1); if((str[0]=='+')||(str[0]=='-')) { hassign++; i++; } for(; i57))&&str[i]!='.') { return(1); } else { if(hasspace) { return(1); } if(str[i]=='.') { if(hasdot) return(1); hasdot++; } else { digit++; } } } } if(hasexp) { if(++i==l) { return(1); } if((str[i]=='+')||(str[i]=='-')) { hassign++; i++; } for(; i57)) { return(1); } else { if(hasspace) { return(1); } digit++; } } } } if(digit) return(0); else return(1); } long long EDFfileCheck::get_long_duration(char *str) { int i, len=8, hasdot=0, dotposition=0; long long value=0, radix; for(i=0; i<8; i++) { if(str[i]==' ') { len = i; break; } } for(i=0; i=0; i--) { value += ((long long)(str[i] - 48)) * radix; radix *= 10; } radix = TIME_DIMENSION / 10; for(i=dotposition+1; i=0; i--) { value += ((long long)(str[i] - 48)) * radix; radix *= 10; } } return(value); } edfbrowser_153_source/PaxHeaders.2978/pagetime_dialog.h0000644000175000001440000000013212251654530021432 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/pagetime_dialog.h0000644000175000001440000000367012251654530021171 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef PAGETIMEFORM1_H #define PAGETIMEFORM1_H #include #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "mainwindow.h" #include "popup_messagewindow.h" class UI_Mainwindow; class UI_Userdefined_timepage_Dialog : public QObject { Q_OBJECT public: UI_Userdefined_timepage_Dialog(QWidget *parent=0); UI_Mainwindow *mainwindow; private: QDialog *set_diplaytime_dialog; QLabel *label1; QPushButton *CloseButton, *OKButton; QTimeEdit *timeEdit1; QTime time1; private slots: void okbutton_pressed(); }; #endif // PAGETIMEFORM1_H edfbrowser_153_source/PaxHeaders.2978/signalcurve.h0000644000175000001440000000013212251654530020642 xustar000000000000000030 mtime=1386699096.468032569 30 atime=1386699096.468032569 30 ctime=1386699096.468032569 edfbrowser_153_source/signalcurve.h0000644000175000001440000001510712251654530020377 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef SIGNALCURVE_H #define SIGNALCURVE_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define MAXSPECTRUMMARKERS 16 #define SC_MAX_PATH_LEN 1024 struct spectrum_markersblock{ int items; double freq[MAXSPECTRUMMARKERS]; int color[MAXSPECTRUMMARKERS]; char label[MAXSPECTRUMMARKERS][17]; double value[MAXSPECTRUMMARKERS]; int method; }; class SignalCurve: public QWidget { Q_OBJECT public: SignalCurve(QWidget *parent=0); QSize sizeHint() const {return minimumSizeHint(); } QSize minimumSizeHint() const {return QSize(30,10); } void setSignalColor(QColor); void setTraceWidth(int); void setBackgroundColor(QColor); void setRasterColor(QColor); void setBorderColor(QColor); void setTextColor(QColor); void setBorderSize(int); void setH_RulerValues(double, double); void setH_label(const char *); void setV_label(const char *); void setUpperLabel1(const char *); void setUpperLabel2(const char *); void setLowerLabel(const char *); void drawCurve(double *, int , double , double ); void drawCurve(int *, int , double , double ); void drawCurve( float *, int , double , double ); void drawLine(int, double, int, double, QColor); void setLineEnabled(bool); void create_button(const char *); void setCursorEnabled(bool); bool isCursorEnabled(void); bool isCursorActive(void); void setPrintEnabled(bool); void setDashBoardEnabled(bool); void setMarker1Enabled(bool); void setMarker1MovableEnabled(bool); void setMarker1Position(double); void setMarker1Color(QColor); double getMarker1Position(void); void setMarker2Enabled(bool); void setMarker2MovableEnabled(bool); void setMarker2Position(double); void setMarker2Color(QColor); double getMarker2Position(void); void setCrosshairColor(QColor); void clear(); void setUpdatesEnabled(bool); void enableSpectrumColors(struct spectrum_markersblock *); void disableSpectrumColors(); void setFillSurfaceEnabled(bool); void setV_rulerEnabled(bool); void setUpsidedownEnabled(bool); int getCursorPosition(void); void shiftCursorPixelsLeft(int); void shiftCursorPixelsRight(int); void shiftCursorIndexLeft(int); void shiftCursorIndexRight(int); signals: void extra_button_clicked(); void dashBoardClicked(); void markerHasMoved(); private slots: void exec_sidemenu(); void print_to_postscript(); void print_to_pdf(); void print_to_image(); void print_to_printer(); void print_to_ascii(); void send_button_event(); private: QDialog *sidemenu; QPushButton *sidemenuButton1, *sidemenuButton2, *sidemenuButton3, *sidemenuButton4, *sidemenuButton5, *sidemenuButton6; QColor SignalColor, BackgroundColor, RasterColor, BorderColor, RulerColor, TextColor, crosshair_1_color, line1Color, backup_color_1, backup_color_2, backup_color_3, backup_color_4, backup_color_5, backup_color_6; QPrinter *printer; QPen Marker1Pen, Marker2Pen; double max_value, min_value, *dbuf, h_ruler_startvalue, h_ruler_endvalue, printsize_x_factor, printsize_y_factor, crosshair_1_value, crosshair_1_value_2, crosshair_1_x_position, line1_start_y, line1_end_y, marker_1_position, marker_2_position; float *fbuf; int bufsize, bordersize, h_ruler_precision, drawHruler, drawVruler, drawcurve_before_raster, tracewidth, extra_button, use_move_events, mouse_x, mouse_y, mouse_old_x, mouse_old_y, crosshair_1_active, crosshair_1_moving, crosshair_1_y_position, crosshair_1_y_value, marker_1_moving, marker_1_x_position, marker_2_moving, marker_2_x_position, line1_start_x, line1_end_x, w, h, old_w, updates_enabled, fillsurface, *ibuf; char h_label[32], v_label[16], upperlabel1[64], upperlabel2[64], lowerlabel[64], extra_button_txt[16], recent_savedir[SC_MAX_PATH_LEN]; bool printEnabled, cursorEnabled, dashBoardEnabled, Marker1Enabled, Marker1MovableEnabled, Marker2Enabled, Marker2MovableEnabled, curveUpSideDown, line1Enabled; struct spectrum_markersblock *spectrum_color; void backup_colors_for_printing(); void restore_colors_after_printing(); void drawWidget(QPainter *, int, int); void drawWidget_to_printer(QPainter *, int, int); int get_directory_from_path(char *, const char *, int); protected: void paintEvent(QPaintEvent *); void mousePressEvent(QMouseEvent *); void mouseReleaseEvent(QMouseEvent *); void mouseMoveEvent(QMouseEvent *); void resizeEvent(QResizeEvent *); }; #endif edfbrowser_153_source/PaxHeaders.2978/nk2edf.cpp0000644000175000001440000000013212251654530020024 xustar000000000000000030 mtime=1386699096.478032517 30 atime=1386699096.478032517 30 ctime=1386699096.478032517 edfbrowser_153_source/nk2edf.cpp0000644000175000001440000011733612251654530017570 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "nk2edf.h" #if defined(__APPLE__) || defined(__MACH__) || defined(__APPLE_CC__) #define fopeno fopen #else #define fseeko fseeko64 #define ftello ftello64 #define fopeno fopen64 #endif #define ELECTRODE_TAG "[ELECTRODE]" #define ELECTRODE_UNTAG "[" #define ELECTRODE_NAME_MAXLEN 256 #define ANNOT_TRACKSIZE 54 UI_NK2EDFwindow::UI_NK2EDFwindow(char *recent_dir) { char txt_string[2048]; recent_opendir = recent_dir; myobjectDialog = new QDialog; myobjectDialog->setMinimumSize(QSize(600, 480)); myobjectDialog->setMaximumSize(QSize(600, 480)); myobjectDialog->setWindowTitle("Nihon Kohden to EDF(+) converter"); myobjectDialog->setModal(TRUE); myobjectDialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); pushButton1 = new QPushButton(myobjectDialog); pushButton1->setGeometry(QRect(20, 430, 100, 26)); pushButton1->setText("Select File"); pushButton2 = new QPushButton(myobjectDialog); pushButton2->setGeometry(QRect(480, 430, 100, 26)); pushButton2->setText("Close"); checkBox1 = new QCheckBox(myobjectDialog); checkBox1->setGeometry(QRect(200, 430, 120, 26)); checkBox1->setText("Create EDF+"); checkBox1->setCheckState(Qt::Checked); textEdit1 = new QTextEdit(myobjectDialog); textEdit1->setGeometry(QRect(20, 20, 560, 380)); textEdit1->setFrameStyle(QFrame::Panel | QFrame::Sunken); textEdit1->setReadOnly(TRUE); textEdit1->setLineWrapMode(QTextEdit::NoWrap); sprintf(txt_string, "Nihon Kohden to EDF(+) converter.\n"); textEdit1->append(txt_string); QObject::connect(pushButton1, SIGNAL(clicked()), this, SLOT(SelectFileButton())); QObject::connect(pushButton2, SIGNAL(clicked()), myobjectDialog, SLOT(close())); myobjectDialog->exec(); } void UI_NK2EDFwindow::SelectFileButton() { FILE *inputfile=NULL, *outputfile=NULL, *logfile=NULL, *pntfile=NULL; int i, j, k, error, ctl_block_cnt, datablock_cnt, total_blocks, edfplus, n_logs=0, n_sublogs=0, total_logs=0, n_logblocks=0, ctlblock_address, wfmblock_address, logblock_address, read_subevents=0; char txt_string[2048], path[MAX_PATH_LENGTH], outputpath[MAX_PATH_LENGTH], logfilepath[MAX_PATH_LENGTH], pntfilepath[MAX_PATH_LENGTH], *log_buf=NULL, *sublog_buf=NULL, scratchpad[256]; pushButton1->setEnabled(FALSE); edfplus = checkBox1->checkState(); total_elapsed_time = 0; strcpy(path, QFileDialog::getOpenFileName(0, "Select inputfile", QString::fromLocal8Bit(recent_opendir), "EEG files (*.eeg *.EEG)").toLocal8Bit().data()); if(!strcmp(path, "")) { pushButton1->setEnabled(TRUE); return; } get_directory_from_path(recent_opendir, path, MAX_PATH_LENGTH); inputfile = fopeno(path, "rb"); if(inputfile==NULL) { snprintf(txt_string, 2048, "can not open file %s for reading.\n", path); textEdit1->append(QString::fromLocal8Bit(txt_string)); pushButton1->setEnabled(TRUE); return; } /***************** check if the EEG file is valid ******************************/ rewind(inputfile); if(fread(scratchpad, 16, 1, inputfile)!=1) { textEdit1->append("error reading .eeg file.\n"); fclose(inputfile); pushButton1->setEnabled(TRUE); return; } scratchpad[16] = 0; if(check_device(scratchpad)) { snprintf(txt_string, 2048, "error, deviceblock has unknown signature: \"%s\"\n", scratchpad); textEdit1->append(txt_string); fclose(inputfile); pushButton1->setEnabled(TRUE); return; } fseeko(inputfile, 0x0081LL, SEEK_SET); if(fread(scratchpad, 16, 1, inputfile)!=1) { textEdit1->append("error reading .eeg file.\n"); fclose(inputfile); pushButton1->setEnabled(TRUE); return; } scratchpad[16] = 0; if(check_device(scratchpad)) { snprintf(txt_string, 2048, "error, controlblock has unknown signature: \"%s\"\n", scratchpad); textEdit1->append(txt_string); fclose(inputfile); pushButton1->setEnabled(TRUE); return; } fseeko(inputfile, 0x17feLL, SEEK_SET); if(fgetc(inputfile)!=0x01) { snprintf(txt_string, 2048, "error, waveformdatablock has wrong signature.\n"); textEdit1->append(txt_string); fclose(inputfile); pushButton1->setEnabled(TRUE); return; } /************************* read logs **********************************************/ if(edfplus) { strncpy(logfilepath, path, MAX_PATH_LENGTH); remove_extension_from_filename(logfilepath); strcat(logfilepath, ".LOG"); logfile = fopeno(logfilepath, "rb"); if(logfile==NULL) { remove_extension_from_filename(logfilepath); strcat(logfilepath, ".log"); logfile = fopeno(logfilepath, "rb"); if(logfile==NULL) { snprintf(txt_string, 2048, "Can not open file %s for reading,\n" "if there is no .log file you can try to create an EDF file instead of EDF+.\n", logfilepath); textEdit1->append(QString::fromLocal8Bit(txt_string)); fclose(inputfile); pushButton1->setEnabled(TRUE); return; } } rewind(logfile); if(fread(scratchpad, 16, 1, logfile)!=1) { textEdit1->append("error reading .log file.\n"); fclose(logfile); fclose(inputfile); pushButton1->setEnabled(TRUE); return; } scratchpad[16] = 0; if(check_device(scratchpad)) { snprintf(txt_string, 2048, "error, .log file has unknown signature: \"%s\"\n", scratchpad); textEdit1->append(QString::fromLocal8Bit(txt_string)); fclose(logfile); fclose(inputfile); pushButton1->setEnabled(TRUE); return; } fseeko(logfile, 0x0091LL, SEEK_SET); n_logblocks = fgetc(logfile); log_buf = (char *)calloc(1, n_logblocks * 11521); if(log_buf==NULL) { textEdit1->append("malloc error\n"); fclose(logfile); fclose(inputfile); pushButton1->setEnabled(TRUE); return; } sublog_buf = (char *)calloc(1, n_logblocks * 11521); if(sublog_buf==NULL) { textEdit1->append("malloc error\n"); fclose(logfile); fclose(inputfile); free(log_buf); pushButton1->setEnabled(TRUE); return; } read_subevents = 1; total_logs = 0; for(i=0; iappend("error reading .log file.\n"); fclose(inputfile); fclose(logfile); free(log_buf); free(sublog_buf); pushButton1->setEnabled(TRUE); return; } fseeko(logfile, (long long)(logblock_address + 0x0012), SEEK_SET); n_logs = fgetc(logfile); fseeko(logfile, (long long)(logblock_address + 0x0014), SEEK_SET); if(fread(log_buf + (total_logs * 45), n_logs * 45, 1, logfile)!=1) { textEdit1->append("error reading .log file.\n"); fclose(inputfile); fclose(logfile); free(log_buf); free(sublog_buf); pushButton1->setEnabled(TRUE); return; } if(read_subevents) { if(fseeko(logfile, 0x0092LL + ((i + 22) * 20) , SEEK_SET)) { read_subevents = 0; } else { if(fread((char *)(&logblock_address), 4, 1, logfile)!=1) { read_subevents = 0; } else { if(fseeko(logfile, logblock_address + 0x0012LL, SEEK_SET)) { read_subevents = 0; } else { n_sublogs = fgetc(logfile); if(n_sublogs != n_logs) { read_subevents = 0; } else { if(fseeko(logfile, logblock_address + 0x0014LL, SEEK_SET)) { read_subevents = 0; } else { if(fread(sublog_buf + (total_logs * 45), n_sublogs * 45, 1, logfile)!=1) { read_subevents = 0; } } } } } } } total_logs += n_logs; } for(i=0; iappend(QString::fromLocal8Bit(txt_string)); fclose(logfile); fclose(inputfile); free(log_buf); free(sublog_buf); pushButton1->setEnabled(TRUE); return; } } rewind(pntfile); if(fread(scratchpad, 16, 1, pntfile)!=1) { textEdit1->append("error reading .pnt file.\n"); fclose(pntfile); fclose(logfile); fclose(inputfile); free(log_buf); free(sublog_buf); pushButton1->setEnabled(TRUE); return; } scratchpad[16] = 0; if(check_device(scratchpad)) { snprintf(txt_string, 2048, "error, .pnt file has unknown signature: \"%s\"\n", scratchpad); textEdit1->append(QString::fromLocal8Bit(txt_string)); fclose(pntfile); fclose(logfile); fclose(inputfile); free(log_buf); free(sublog_buf); pushButton1->setEnabled(TRUE); return; } } /***************** initialize labels **************************************/ for(i=0; i<256; i++) { strcpy(labels[i], "- "); } strcpy(labels[0], "EEG FP1 "); strcpy(labels[1], "EEG FP2 "); strcpy(labels[2], "EEG F3 "); strcpy(labels[3], "EEG F4 "); strcpy(labels[4], "EEG C3 "); strcpy(labels[5], "EEG C4 "); strcpy(labels[6], "EEG P3 "); strcpy(labels[7], "EEG P4 "); strcpy(labels[8], "EEG O1 "); strcpy(labels[9], "EEG O2 "); strcpy(labels[10], "EEG F7 "); strcpy(labels[11], "EEG F8 "); strcpy(labels[12], "EEG T3 "); strcpy(labels[13], "EEG T4 "); strcpy(labels[14], "EEG T5 "); strcpy(labels[15], "EEG T6 "); strcpy(labels[16], "EEG FZ "); strcpy(labels[17], "EEG CZ "); strcpy(labels[18], "EEG PZ "); strcpy(labels[19], "EEG E "); strcpy(labels[20], "EEG PG1 "); strcpy(labels[21], "EEG PG2 "); strcpy(labels[22], "EEG A1 "); strcpy(labels[23], "EEG A2 "); strcpy(labels[24], "EEG T1 "); strcpy(labels[25], "EEG T2 "); for(i=26; i<35; i++) { sprintf(labels[i], "EEG X%i ", i - 25); } strcpy(labels[35], "EEG X10 "); strcpy(labels[36], "EEG X11 "); for(i=42; i<74; i++) { sprintf(labels[i], "DC%02i ", i - 41); } strcpy(labels[74], "EEG BN1 "); strcpy(labels[75], "EEG BN2 "); strcpy(labels[76], "EEG Mark1 "); strcpy(labels[77], "EEG Mark2 "); strcpy(labels[100], "EEG X12/BP1 "); strcpy(labels[101], "EEG X13/BP2 "); strcpy(labels[102], "EEG X14/BP3 "); strcpy(labels[103], "EEG X15/BP4 "); for(i=104; i<188; i++) { sprintf(labels[i], "EEG X%i ", i - 88); } for(i=188; i<254; i++) { sprintf(labels[i], "EEG X%i ", i - 88); } strcpy(labels[255], "Z "); if(read_21e_file(path)) { textEdit1->append("Can not open *.21e file, converter will use default electrode names."); } /***************** start conversion **************************************/ total_blocks = 0; fseeko(inputfile, 0x0091LL, SEEK_SET); ctl_block_cnt = fgetc(inputfile); if(ctl_block_cnt==EOF) { textEdit1->append("error reading inputfile.\n"); pushButton1->setEnabled(TRUE); fclose(inputfile); if(edfplus) { fclose(logfile); free(log_buf); free(sublog_buf); fclose(pntfile); } return; } for(i=0; iappend("error reading inputfile.\n"); pushButton1->setEnabled(TRUE); fclose(inputfile); if(edfplus) { fclose(logfile); free(log_buf); free(sublog_buf); fclose(pntfile); } return; } fseeko(inputfile, (long long)(ctlblock_address + 17), SEEK_SET); datablock_cnt = fgetc(inputfile); if(datablock_cnt==EOF) { textEdit1->append("error reading inputfile.\n"); pushButton1->setEnabled(TRUE); fclose(inputfile); if(edfplus) { fclose(logfile); free(log_buf); free(sublog_buf); fclose(pntfile); } return; } for(j=0; jappend("error reading inputfile.\n"); pushButton1->setEnabled(TRUE); fclose(inputfile); if(edfplus) { fclose(logfile); free(log_buf); free(sublog_buf); fclose(pntfile); } return; } /********************************************************************/ strcpy(outputpath, path); if(edfplus) sprintf(outputpath + strlen(path) - 4, "_%u-%u+.edf", i + 1, j + 1); else sprintf(outputpath + strlen(path) - 4, "_%u-%u.edf", i + 1, j + 1); outputfile = fopeno(outputpath, "wb"); if(outputfile==NULL) { snprintf(txt_string, 2048, "can not open file %s for writing.\n", outputpath); textEdit1->append(QString::fromLocal8Bit(txt_string)); pushButton1->setEnabled(TRUE); fclose(inputfile); if(edfplus) { fclose(logfile); free(log_buf); free(sublog_buf); fclose(pntfile); } return; } textEdit1->append("Converting a waveform datablock..."); for(k=0; k<10; k++) qApp->processEvents(); error = convert_nk2edf(inputfile, outputfile, pntfile, wfmblock_address, edfplus, total_logs, log_buf, read_subevents); if(error==0) { snprintf(txt_string, 2048, "to %s", outputpath); textEdit1->append(txt_string); } if(error==1) textEdit1->append("malloc error.\n"); if(error==2) textEdit1->append("read error during conversion.\n"); if(error==3) textEdit1->append("write error during conversion.\n"); if(error==4) textEdit1->append("format error.\n"); if(fclose(outputfile)) { textEdit1->append("error closing outputfile.\n"); pushButton1->setEnabled(TRUE); fclose(inputfile); if(edfplus) { fclose(logfile); fclose(pntfile); free(log_buf); free(sublog_buf); } return; } if(error) { if(edfplus) { fclose(logfile); fclose(pntfile); free(log_buf); free(sublog_buf); } pushButton1->setEnabled(TRUE); return; } total_blocks++; /**************************************************************/ } } if(fclose(inputfile)) textEdit1->append("error closing inputfile.\n"); if(edfplus) { if(fclose(logfile)) textEdit1->append("error closing .log file.\n"); if(fclose(pntfile)) textEdit1->append("error closing .pnt file.\n"); free(log_buf); free(sublog_buf); } if(edfplus) snprintf(txt_string, 2048, "Converted %u waveformblock(s) successfully to EDF+.\n", total_blocks); else snprintf(txt_string, 2048, "Converted %u waveformblock(s) successfully to EDF.\n", total_blocks); textEdit1->append(txt_string); pushButton1->setEnabled(TRUE); } int UI_NK2EDFwindow::convert_nk2edf(FILE *inputfile, FILE *outputfile, FILE *pntfile, int offset, int edfplus, int n_logs, char *log_buf, int read_subevents) { int i, j, k, p, temp, channels, samplefrequency, record_duration, raster, record_size, max_buf_records, bufsize, records_in_buf, seconds, deci_seconds, left_records, elapsed_time, error, records_written, progress_steps, n_log_processed; char *buf, *annotations, scratchpad[48]; /************************* filter events ******************************************/ for(i=0; i=total_elapsed_time) break; } log_buf += i * 45; n_logs -= i; /************************* write EDF-header ***************************************/ rewind(outputfile); fprintf(outputfile, "0 "); if(edfplus) { error = 0; fseeko(pntfile, 0x0604LL, SEEK_SET); if(fread(scratchpad, 10, 1, pntfile)!=1) { return(2); } scratchpad[10] = 0; latin1_to_ascii(scratchpad, strlen(scratchpad)); for(i=0; i<10; i++) { if(scratchpad[i]==0) break; if(scratchpad[i]==' ') scratchpad[i] = '_'; } if(i) { p = i; if(fwrite(scratchpad, i, 1, outputfile)!=1) { return(3); } } else { fputc('X', outputfile); p = 1; } fputc(' ', outputfile); p++; fseeko(pntfile, 0x064aLL, SEEK_SET); if(fread(scratchpad, 6, 1, pntfile)!=1) { return(2); } if(!strncmp(scratchpad, "Male", 4)) fputc('M', outputfile); else { if(!strncmp(scratchpad, "Female", 6)) fputc('F', outputfile); else fputc('X', outputfile); } p++; fputc(' ', outputfile); p++; fseeko(pntfile, 0x0668LL, SEEK_SET); if(fread(scratchpad, 2, 1, pntfile)!=1) { return(2); } scratchpad[2] = 0; temp = atoi(scratchpad); if((temp<1)||(temp>31)) error = 1; for(i=0; i<2; i++) { if((scratchpad[i]<'0')||(scratchpad[i]>'9')) { error = 1; break; } } fseeko(pntfile, 0x0665LL, SEEK_SET); if(fread(scratchpad, 2, 1, pntfile)!=1) { return(2); } scratchpad[2] = 0; temp = atoi(scratchpad); if((temp<1)||(temp>12)) error = 1; fseeko(pntfile, 0x0660LL, SEEK_SET); if(fread(scratchpad, 4, 1, pntfile)!=1) { return(2); } scratchpad[4] = 0; temp = atoi(scratchpad); if((temp<1)||(temp>9999)) error = 1; for(i=0; i<4; i++) { if((scratchpad[i]<'0')||(scratchpad[i]>'9')) { error = 1; break; } } if(error) { fputc('X', outputfile); p++; } else { fseeko(pntfile, 0x0668LL, SEEK_SET); if(fread(scratchpad, 2, 1, pntfile)!=1) { return(2); } scratchpad[2] = 0; temp = atoi(scratchpad); if((temp<1)||(temp>31)) { snprintf(scratchpad, 48, "01"); error = 1; } for(i=0; i<2; i++) { if((scratchpad[i]<'0')||(scratchpad[i]>'9')) { snprintf(scratchpad, 48, "01"); error = 1; break; } } if(fwrite(scratchpad, 2, 1, outputfile)!=1) { return(3); } p += 2; fputc('-', outputfile); p++; fseeko(pntfile, 0x0665LL, SEEK_SET); if(fread(scratchpad, 2, 1, pntfile)!=1) { return(2); } scratchpad[2] = 0; temp = atoi(scratchpad); switch(temp) { case 1 : strcpy(scratchpad, "JAN"); break; case 2 : strcpy(scratchpad, "FEB"); break; case 3 : strcpy(scratchpad, "MAR"); break; case 4 : strcpy(scratchpad, "APR"); break; case 5 : strcpy(scratchpad, "MAY"); break; case 6 : strcpy(scratchpad, "JUN"); break; case 7 : strcpy(scratchpad, "JUL"); break; case 8 : strcpy(scratchpad, "AUG"); break; case 9 : strcpy(scratchpad, "SEP"); break; case 10 : strcpy(scratchpad, "OCT"); break; case 11 : strcpy(scratchpad, "NOV"); break; case 12 : strcpy(scratchpad, "DEC"); break; default : strcpy(scratchpad, "JAN"); error = 1; break; } if(fwrite(scratchpad, 3, 1, outputfile)!=1) { return(3); } p += 3; fputc('-', outputfile); p++; fseeko(pntfile, 0x0660LL, SEEK_SET); if(fread(scratchpad, 4, 1, pntfile)!=1) { return(2); } scratchpad[4] = 0; temp = atoi(scratchpad); if((temp<1)||(temp>9999)) { snprintf(scratchpad, 48, "1800"); error = 1; } for(i=0; i<4; i++) { if((scratchpad[i]<'0')||(scratchpad[i]>'9')) { snprintf(scratchpad, 48, "1800"); error = 1; break; } } if(fwrite(scratchpad, 4, 1, outputfile)!=1) { return(3); } p += 4; } fputc(' ', outputfile); p++; fseeko(pntfile, 0x062eLL, SEEK_SET); if(fread(scratchpad, 20, 1, pntfile)!=1) { return(2); } scratchpad[20] = 0; latin1_to_ascii(scratchpad, strlen(scratchpad)); for(i=0; i<20; i++) { if(scratchpad[i]==0) break; if(scratchpad[i]==' ') scratchpad[i] = '_'; } if(i) { p += i; if(fwrite(scratchpad, i, 1, outputfile)!=1) { return(3); } } else { fputc('X', outputfile); p++; } for(i=0; i<80-p; i++) fputc(' ', outputfile); if(fwrite("Startdate ", 10, 1, outputfile)!=1) { return(3); } p = 10; error = 0; fseeko(pntfile, 0x0046LL, SEEK_SET); if(fread(scratchpad, 2, 1, pntfile)!=1) { return(2); } scratchpad[2] = 0; temp = atoi(scratchpad); if((temp<1)||(temp>31)) error = 1; for(i=0; i<2; i++) { if((scratchpad[i]<'0')||(scratchpad[i]>'9')) { error = 1; break; } } fseeko(pntfile, 0x0044LL, SEEK_SET); if(fread(scratchpad, 2, 1, pntfile)!=1) { return(2); } scratchpad[2] = 0; temp = atoi(scratchpad); if((temp<1)||(temp>12)) error = 1; fseeko(pntfile, 0x0040LL, SEEK_SET); if(fread(scratchpad, 4, 1, pntfile)!=1) { return(2); } scratchpad[4] = 0; temp = atoi(scratchpad); if((temp<1970)||(temp>9999)) error = 1; for(i=0; i<4; i++) { if((scratchpad[i]<'0')||(scratchpad[i]>'9')) { error = 1; break; } } if(error) { fputc('X', outputfile); p++; } else { fseeko(pntfile, 0x0046LL, SEEK_SET); if(fread(scratchpad, 2, 1, pntfile)!=1) { return(2); } scratchpad[2] = 0; temp = atoi(scratchpad); if((temp<1)||(temp>31)) snprintf(scratchpad, 48, "01"); for(i=0; i<2; i++) { if((scratchpad[i]<'0')||(scratchpad[i]>'9')) { snprintf(scratchpad, 48, "01"); break; } } if(fwrite(scratchpad, 2, 1, outputfile)!=1) { return(3); } fputc('-', outputfile); fseeko(pntfile, 0x0044LL, SEEK_SET); if(fread(scratchpad, 2, 1, pntfile)!=1) { return(2); } scratchpad[2] = 0; temp = atoi(scratchpad); switch(temp) { case 1 : strcpy(scratchpad, "JAN"); break; case 2 : strcpy(scratchpad, "FEB"); break; case 3 : strcpy(scratchpad, "MAR"); break; case 4 : strcpy(scratchpad, "APR"); break; case 5 : strcpy(scratchpad, "MAY"); break; case 6 : strcpy(scratchpad, "JUN"); break; case 7 : strcpy(scratchpad, "JUL"); break; case 8 : strcpy(scratchpad, "AUG"); break; case 9 : strcpy(scratchpad, "SEP"); break; case 10 : strcpy(scratchpad, "OCT"); break; case 11 : strcpy(scratchpad, "NOV"); break; case 12 : strcpy(scratchpad, "DEC"); break; default : strcpy(scratchpad, "JAN"); break; } if(fwrite(scratchpad, 3, 1, outputfile)!=1) { return(3); } fputc('-', outputfile); fseeko(pntfile, 0x0040LL, SEEK_SET); if(fread(scratchpad, 4, 1, pntfile)!=1) { return(2); } scratchpad[4] = 0; temp = atoi(scratchpad); if((temp<1)||(temp>9999)) snprintf(scratchpad, 48, "1800"); for(i=0; i<4; i++) { if((scratchpad[i]<'0')||(scratchpad[i]>'9')) { snprintf(scratchpad, 48, "1800"); break; } } if(fwrite(scratchpad, 4, 1, outputfile)!=1) { return(3); } p += 11; } fputc(' ', outputfile); p++; fseeko(pntfile, 0x061cLL, SEEK_SET); if(fread(scratchpad, 10, 1, pntfile)!=1) { return(2); } scratchpad[10] = 0; latin1_to_ascii(scratchpad, strlen(scratchpad)); for(i=0; i<10; i++) { if(scratchpad[i]==0) break; if(scratchpad[i]==' ') scratchpad[i] = '_'; } if(i) { p += i; if(fwrite(scratchpad, i, 1, outputfile)!=1) { return(3); } } else { fputc('X', outputfile); p++; } fputc(' ', outputfile); p++; fseeko(pntfile, 0x06aaLL, SEEK_SET); if(fread(scratchpad, 20, 1, pntfile)!=1) { return(2); } scratchpad[20] = 0; latin1_to_ascii(scratchpad, strlen(scratchpad)); for(i=0; i<20; i++) { if(scratchpad[i]==0) break; if(scratchpad[i]==' ') scratchpad[i] = '_'; } if(i) { p += i; if(fwrite(scratchpad, i, 1, outputfile)!=1) { return(3); } } else { fputc('X', outputfile); p++; } fputc(' ', outputfile); p++; if(fwrite("Nihon_Kohden_", 13, 1, outputfile)!=1) { return(3); } p += 13; rewind(inputfile); if(fread(scratchpad, 16, 1, inputfile)!=1) { return(2); } scratchpad[16] = 0; latin1_to_ascii(scratchpad, strlen(scratchpad)); for(i=0; i<16; i++) { if(scratchpad[i]==0) break; if(scratchpad[i]==' ') scratchpad[i] = '_'; } if(fwrite(scratchpad, i, 1, outputfile)!=1) { return(3); } p += i; for(i=0; i<80-p; i++) fputc(' ', outputfile); } else { fseeko(inputfile, 0x004fLL, SEEK_SET); if(fread(scratchpad, 32, 1, inputfile)!=1) { return(2); } scratchpad[32] = 0; latin1_to_ascii(scratchpad, strlen(scratchpad)); for(i=0; i<32; i++) { if(scratchpad[i]==0) break; } p = 80 - i; if(fwrite(scratchpad, i, 1, outputfile)!=1) { return(3); } for(i=0; i> 4) * 10) + (temp & 15)); fseeko(inputfile, (long long)(0x0015 + offset), SEEK_SET); temp = fgetc(inputfile); fprintf(outputfile, "%02u.", ((temp >> 4) * 10) + (temp & 15)); fseeko(inputfile, (long long)(0x0014 + offset), SEEK_SET); temp = fgetc(inputfile); fprintf(outputfile, "%02u", ((temp >> 4) * 10) + (temp & 15)); fseeko(inputfile, (long long)(0x0017 + offset), SEEK_SET); temp = fgetc(inputfile); fprintf(outputfile, "%02u.", ((temp >> 4) * 10) + (temp & 15)); temp = fgetc(inputfile); fprintf(outputfile, "%02u.", ((temp >> 4) * 10) + (temp & 15)); temp = fgetc(inputfile); fprintf(outputfile, "%02u", ((temp >> 4) * 10) + (temp & 15)); fseeko(inputfile, (long long)(0x0026 + offset), SEEK_SET); channels = fgetc(inputfile) + 1; if(edfplus) { fprintf(outputfile, "%-8u", (channels + 1) * 256 + 256); fprintf(outputfile, "EDF+C"); for(i=0; i<39; i++) fputc(' ', outputfile); } else { fprintf(outputfile, "%-8u", channels * 256 + 256); for(i=0; i<44; i++) fputc(' ', outputfile); } fseeko(inputfile, (long long)(0x001c + offset), SEEK_SET); if(fread((char *)(&record_duration), 4, 1, inputfile)!=1) { return(2); } if((record_duration < 10) || (record_duration > 99999999)) { return(4); } fprintf(outputfile, "%-8u", record_duration); fprintf(outputfile, "0.1 "); if(edfplus) fprintf(outputfile, "%-4u", channels + 1); else fprintf(outputfile, "%-4u", channels); for(i=0; i<(channels - 1); i++) { fseeko(inputfile, (long long)(0x0027 + (i * 10) + offset), SEEK_SET); temp = fgetc(inputfile); if((temp < 0) || (temp > 255)) { fprintf(outputfile, "%s", "- "); } else { fprintf(outputfile, "%s", labels[temp]); } } fprintf(outputfile, "Events/Markers "); if(edfplus) fprintf(outputfile, "EDF Annotations "); for(i=0; i<(channels * 80); i++) fputc(' ', outputfile); if(edfplus) for(i=0; i<80; i++) fputc(' ', outputfile); for(i=0; i<(channels - 1); i++) { fseeko(inputfile, (long long)(0x0027 + (i * 10) + offset), SEEK_SET); temp = fgetc(inputfile); if(((temp<42)||(temp>73)) && (temp!=76) && (temp!=77)) fprintf(outputfile, "uV "); else fprintf(outputfile, "mV "); } fprintf(outputfile, " "); if(edfplus) fprintf(outputfile, " "); for(i=0; i<(channels - 1); i++) { fseeko(inputfile, (long long)(0x0027 + (i * 10) + offset), SEEK_SET); temp = fgetc(inputfile); if(((temp<42)||(temp>73)) && (temp!=76) && (temp!=77)) fprintf(outputfile, "-3200 "); else fprintf(outputfile, "-12002.9"); } fprintf(outputfile, "-1 "); if(edfplus) fprintf(outputfile, "-1 "); for(i=0; i<(channels - 1); i++) { fseeko(inputfile, (long long)(0x0027 + (i * 10) + offset), SEEK_SET); temp = fgetc(inputfile); if(((temp<42)||(temp>73)) && (temp!=76) && (temp!=77)) fprintf(outputfile, "3199.902"); else fprintf(outputfile, "12002.56"); } fprintf(outputfile, "1 "); if(edfplus) fprintf(outputfile, "1 "); for(i=0; imax_buf_records) records_in_buf = max_buf_records; else records_in_buf = left_records; for(i=0; iprocessEvents(); } for(j=0; j=total_elapsed_time) { elapsed_time -= total_elapsed_time; if(elapsed_time<(record_duration / 10)) { p++; p += sprintf(annotations + p, "%+i", elapsed_time); if(read_subevents) { annotations[p] = '.'; p++; strncpy(annotations + p, log_buf + (n_log_processed * 45) + 26, 3); p += 3; } annotations[p++] = 20; strncpy(annotations + p, log_buf + (n_log_processed * 45), 20); p += 20; annotations[p] = 20; n_log_processed++; break; } } } } if(++deci_seconds>9) { deci_seconds = 0; seconds++; } records_written++; } if(fwrite(buf, records_in_buf * record_size, 1, outputfile)!=1) { free(buf); return(3); } left_records -= records_in_buf; } progress.reset(); total_elapsed_time += record_duration / 10; free(buf); return(0); } int UI_NK2EDFwindow::check_device(char *str) { int error = 1; if(!strncmp(str, "EEG-1100A V01.00", 16)) error = 0; if(!strncmp(str, "EEG-1100B V01.00", 16)) error = 0; if(!strncmp(str, "EEG-1100C V01.00", 16)) error = 0; if(!strncmp(str, "QI-403A V01.00", 16)) error = 0; if(!strncmp(str, "QI-403A V02.00", 16)) error = 0; if(!strncmp(str, "EEG-2100 V01.00", 16)) error = 0; if(!strncmp(str, "EEG-2100 V02.00", 16)) error = 0; if(!strncmp(str, "DAE-2100D V01.30", 16)) error = 0; if(!strncmp(str, "DAE-2100D V02.00", 16)) error = 0; // if(!strncmp(str, "EEG-1200A V01.00", 16)) error = 0; return(error); } int UI_NK2EDFwindow::read_21e_file(char *e21filepath) { int n, flag_eleclines=0, idx; char *electrode_name, electrode_name_buffer[ELECTRODE_NAME_MAXLEN], scratchpad[64], *charpntr; FILE *inputfile; remove_extension_from_filename(e21filepath); strcat(e21filepath, ".21E"); inputfile = fopeno(e21filepath, "rb"); if(inputfile==NULL) { remove_extension_from_filename(e21filepath); strcat(e21filepath, ".21e"); inputfile = fopeno(e21filepath, "rb"); if(inputfile==NULL) { return(1); } } while (!feof(inputfile)) { charpntr = fgets(electrode_name_buffer, ELECTRODE_NAME_MAXLEN-1, inputfile); if(charpntr == NULL) { break; } if(strncmp(electrode_name_buffer, ELECTRODE_TAG, strlen(ELECTRODE_TAG)) == 0) { flag_eleclines = 1; } else { if(strncmp(electrode_name_buffer, ELECTRODE_UNTAG, strlen(ELECTRODE_UNTAG)) == 0) { flag_eleclines = 0; } } if(flag_eleclines) { if(strtok(electrode_name_buffer, "=") != NULL) { idx = atoi(electrode_name_buffer); electrode_name = strtok(NULL, "="); if(electrode_name != NULL) { n = strlen(electrode_name); if((n > 0)&&(electrode_name[n-1] == 10)) { electrode_name[n-1] = 0; } if((n > 1)&&(electrode_name[n-2] == 13)) { electrode_name[n-2] = 0; } n = strlen(electrode_name); if((idx >= 0) && (idx < 256)) { if(n > 0) { strncpy(scratchpad, electrode_name, 16); strcat(scratchpad, " "); latin1_to_ascii(scratchpad, 16); scratchpad[16] = 0; strcpy(labels[idx], scratchpad); } else { strcpy(labels[idx], "- "); } } } } } } fclose(inputfile); return(0); } edfbrowser_153_source/PaxHeaders.2978/ecg_export.h0000644000175000001440000000013212251654530020457 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/ecg_export.h0000644000175000001440000000450712251654530020216 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef ECGEXPORTCLASS_H #define ECGEXPORTCLASS_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "mainwindow.h" #include "viewcurve.h" #include "utils.h" #include "filteredblockread.h" #include "edf_annot_list.h" class UI_Mainwindow; class ViewCurve; class UI_ECGExport : public QObject { Q_OBJECT public: UI_ECGExport(QWidget *parent); UI_Mainwindow *mainwindow; private: QDialog *myobjectDialog; QListWidget *list; QPushButton *startButton, *cancelButton; QGroupBox *groupBox1; QVBoxLayout *vbox1; QRadioButton *radioButton1, *radioButton2, *radioButton3; QCheckBox *checkBox1, *checkBox2; void load_signalcomps(void); private slots: void Export_RR_intervals(); }; #endif edfbrowser_153_source/PaxHeaders.2978/options_dialog.cpp0000644000175000001440000000013212251654530021665 xustar000000000000000030 mtime=1386699096.478032517 30 atime=1386699096.478032517 30 ctime=1386699096.478032517 edfbrowser_153_source/options_dialog.cpp0000644000175000001440000015206712251654530021431 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "options_dialog.h" UI_OptionsDialog::UI_OptionsDialog(QWidget *w_parent) { int i, showminimized=0; mainwindow = (UI_Mainwindow *)w_parent; optionsdialog = new QDialog(w_parent); if(QApplication::desktop()->screenGeometry().height() < 900) { showminimized = 1; } if(showminimized) { optionsdialog->setMinimumSize(480, 500); optionsdialog->setMaximumSize(480, 820); scrollarea = new QScrollArea; scrollarea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); frame = new QFrame; frame->setMinimumSize(440, 780); frame->setMaximumSize(440, 780); } else { optionsdialog->setMinimumSize(440, 780); optionsdialog->setMaximumSize(440, 780); } optionsdialog->setWindowTitle("Settings"); optionsdialog->setModal(TRUE); optionsdialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); tabholder = new QTabWidget; CloseButton = new QPushButton; CloseButton->setText("Close"); /////////////////////////////////////// tab 1 Colors /////////////////////////////////////////////////////////////////////// tab1 = new QWidget; label1 = new QLabel(tab1); label1->setGeometry(QRect(20, 15, 200, 25)); label1->setText("Background color"); BgColorButton = new SpecialButton(tab1); BgColorButton->setGeometry(QRect(240, 20, 60, 15)); BgColorButton->setColor(mainwindow->maincurve->backgroundcolor); label2 = new QLabel(tab1); label2->setGeometry(QRect(20, 55, 200, 25)); label2->setText("Small ruler color"); SrColorButton = new SpecialButton(tab1); SrColorButton->setGeometry(QRect(240, 60, 60, 15)); SrColorButton->setColor(mainwindow->maincurve->small_ruler_color); label3 = new QLabel(tab1); label3->setGeometry(QRect(20, 95, 200, 25)); label3->setText("Big ruler color"); BrColorButton = new SpecialButton(tab1); BrColorButton->setGeometry(QRect(240, 100, 60, 15)); BrColorButton->setColor(mainwindow->maincurve->big_ruler_color); label4 = new QLabel(tab1); label4->setGeometry(QRect(20, 135, 200, 25)); label4->setText("Mouse rectangle color"); MrColorButton = new SpecialButton(tab1); MrColorButton->setGeometry(QRect(240, 140, 60, 15)); MrColorButton->setColor(mainwindow->maincurve->mouse_rect_color); label5 = new QLabel(tab1); label5->setGeometry(QRect(20, 175, 200, 25)); label5->setText("Text color"); TxtColorButton = new SpecialButton(tab1); TxtColorButton->setGeometry(QRect(240, 180, 60, 15)); TxtColorButton->setColor(mainwindow->maincurve->text_color); label6 = new QLabel(tab1); label6->setGeometry(QRect(20, 215, 200, 25)); label6->setText("Signals color"); SigColorButton = new SpecialButton(tab1); SigColorButton->setGeometry(QRect(240, 220, 60, 15)); SigColorButton->setColor((Qt::GlobalColor)mainwindow->maincurve->signal_color); label7 = new QLabel(tab1); label7->setGeometry(QRect(20, 255, 200, 25)); label7->setText("Baseline color"); checkbox3 = new QCheckBox(tab1); checkbox3->setGeometry(QRect(200, 258, 20, 20)); checkbox3->setTristate(FALSE); if(mainwindow->show_baselines) { checkbox3->setCheckState(Qt::Checked); } else { checkbox3->setCheckState(Qt::Unchecked); } BaseColorButton = new SpecialButton(tab1); BaseColorButton->setGeometry(QRect(240, 260, 60, 15)); BaseColorButton->setColor(mainwindow->maincurve->baseline_color); label8 = new QLabel(tab1); label8->setGeometry(QRect(20, 295, 200, 25)); label8->setText("Crosshair color"); Crh1ColorButton = new SpecialButton(tab1); Crh1ColorButton->setGeometry(QRect(240, 300, 60, 15)); Crh1ColorButton->setColor((Qt::GlobalColor)mainwindow->maincurve->crosshair_1.color); label9 = new QLabel(tab1); label9->setGeometry(QRect(20, 335, 200, 25)); label9->setText("2th Crosshair color"); Crh2ColorButton = new SpecialButton(tab1); Crh2ColorButton->setGeometry(QRect(240, 340, 60, 15)); Crh2ColorButton->setColor((Qt::GlobalColor)mainwindow->maincurve->crosshair_2.color); label10 = new QLabel(tab1); label10->setGeometry(QRect(20, 375, 200, 25)); label10->setText("Floating ruler color"); FrColorButton = new SpecialButton(tab1); FrColorButton->setGeometry(QRect(240, 380, 60, 15)); FrColorButton->setColor((Qt::GlobalColor)mainwindow->maincurve->floating_ruler_color); label12 = new QLabel(tab1); label12->setGeometry(QRect(20, 415, 200, 25)); label12->setText("Annotation marker"); checkbox2 = new QCheckBox(tab1); checkbox2->setGeometry(QRect(200, 418, 20, 20)); checkbox2->setTristate(FALSE); if(mainwindow->show_annot_markers) { checkbox2->setCheckState(Qt::Checked); } else { checkbox2->setCheckState(Qt::Unchecked); } AnnotMkrButton = new SpecialButton(tab1); AnnotMkrButton->setGeometry(QRect(240, 420, 60, 15)); AnnotMkrButton->setColor(mainwindow->maincurve->annot_marker_color); label11 = new QLabel(tab1); label11->setGeometry(QRect(20, 455, 200, 25)); label11->setText("Print in grayscale"); checkbox1 = new QCheckBox(tab1); checkbox1->setGeometry(QRect(200, 458, 20, 20)); checkbox1->setTristate(FALSE); if(mainwindow->maincurve->blackwhite_printing) { checkbox1->setCheckState(Qt::Checked); } else { checkbox1->setCheckState(Qt::Unchecked); } label13 = new QLabel(tab1); label13->setGeometry(QRect(20, 495, 200, 25)); label13->setText("Clip signals to pane"); checkbox4 = new QCheckBox(tab1); checkbox4->setGeometry(QRect(200, 498, 20, 20)); checkbox4->setTristate(FALSE); if(mainwindow->clip_to_pane) { checkbox4->setCheckState(Qt::Checked); } else { checkbox4->setCheckState(Qt::Unchecked); } colorSchema_Dark_Button = new QPushButton(tab1); colorSchema_Dark_Button->setGeometry(QRect(140, 540, 140, 20)); colorSchema_Dark_Button->setText("Colorschema \"Dark\""); colorSchema_NK_Button = new QPushButton(tab1); colorSchema_NK_Button->setGeometry(QRect(140, 570, 140, 20)); colorSchema_NK_Button->setText("Colorschema \"NK\""); DefaultButton = new QPushButton(tab1); DefaultButton->setGeometry(QRect(140, 600, 140, 20)); DefaultButton->setText("Default colorschema"); saveColorSchemaButton = new QPushButton(tab1); saveColorSchemaButton->setGeometry(QRect(140, 630, 140, 20)); saveColorSchemaButton->setText("Save colorschema"); loadColorSchemaButton = new QPushButton(tab1); loadColorSchemaButton->setGeometry(QRect(140, 660, 140, 20)); loadColorSchemaButton->setText("Load colorschema"); QObject::connect(BgColorButton, SIGNAL(clicked(SpecialButton *)), this, SLOT(BgColorButtonClicked(SpecialButton *))); QObject::connect(SrColorButton, SIGNAL(clicked(SpecialButton *)), this, SLOT(SrColorButtonClicked(SpecialButton *))); QObject::connect(BrColorButton, SIGNAL(clicked(SpecialButton *)), this, SLOT(BrColorButtonClicked(SpecialButton *))); QObject::connect(MrColorButton, SIGNAL(clicked(SpecialButton *)), this, SLOT(MrColorButtonClicked(SpecialButton *))); QObject::connect(TxtColorButton, SIGNAL(clicked(SpecialButton *)), this, SLOT(TxtColorButtonClicked(SpecialButton *))); QObject::connect(SigColorButton, SIGNAL(clicked(SpecialButton *)), this, SLOT(SigColorButtonClicked(SpecialButton *))); QObject::connect(BaseColorButton, SIGNAL(clicked(SpecialButton *)), this, SLOT(BaseColorButtonClicked(SpecialButton *))); QObject::connect(Crh1ColorButton, SIGNAL(clicked(SpecialButton *)), this, SLOT(Crh1ColorButtonClicked(SpecialButton *))); QObject::connect(Crh2ColorButton, SIGNAL(clicked(SpecialButton *)), this, SLOT(Crh2ColorButtonClicked(SpecialButton *))); QObject::connect(FrColorButton, SIGNAL(clicked(SpecialButton *)), this, SLOT(FrColorButtonClicked(SpecialButton *))); QObject::connect(AnnotMkrButton, SIGNAL(clicked(SpecialButton *)), this, SLOT(AnnotMkrButtonClicked(SpecialButton *))); QObject::connect(checkbox1, SIGNAL(stateChanged(int)), this, SLOT(checkbox1Clicked(int))); QObject::connect(checkbox2, SIGNAL(stateChanged(int)), this, SLOT(checkbox2Clicked(int))); QObject::connect(checkbox3, SIGNAL(stateChanged(int)), this, SLOT(checkbox3Clicked(int))); QObject::connect(checkbox4, SIGNAL(stateChanged(int)), this, SLOT(checkbox4Clicked(int))); QObject::connect(saveColorSchemaButton, SIGNAL(clicked()), this, SLOT(saveColorSchemaButtonClicked())); QObject::connect(loadColorSchemaButton, SIGNAL(clicked()), this, SLOT(loadColorSchemaButtonClicked())); QObject::connect(DefaultButton, SIGNAL(clicked()), this, SLOT(DefaultButtonClicked())); QObject::connect(colorSchema_NK_Button, SIGNAL(clicked()), this, SLOT(loadColorSchema_NK())); QObject::connect(colorSchema_Dark_Button, SIGNAL(clicked()), this, SLOT(loadColorSchema_Dark())); tabholder->addTab(tab1, "Colors"); /////////////////////////////////////// tab 2 Calibration /////////////////////////////////////////////////////////////////////// tab2 = new QWidget; checkbox2_1 = new QCheckBox("Manually override automatic DPI settings", tab2); checkbox2_1->setGeometry(85, 560, 300, 20); checkbox2_1->setTristate(FALSE); if(mainwindow->auto_dpi) { checkbox2_1->setCheckState(Qt::Unchecked); } else { checkbox2_1->setCheckState(Qt::Checked); } slabel2_1 = new SpecialButton(tab2); slabel2_1->setGeometry(30, 20, 10, 445); slabel2_1->setColor(Qt::black); slabel2_3 = new SpecialButton(tab2); slabel2_3->setGeometry(30, 500, 355, 10); slabel2_3->setColor(Qt::black); label2_2 = new QLabel(tab2); label2_2->setGeometry(85, 50, 220, 50); label2_2->setText("Measure the length of the black\nrectangles and enter the values."); spinbox2_1 = new QSpinBox(tab2); spinbox2_1->setGeometry(85, 240, 100, 20); spinbox2_1->setSuffix(" mm"); spinbox2_1->setMinimum(10); spinbox2_1->setMaximum(500); spinbox2_1->setValue((int)(4450.0 / (1.0 / mainwindow->pixelsizefactor))); spinbox2_2 = new QSpinBox(tab2); spinbox2_2->setGeometry(170, 450, 100, 20); spinbox2_2->setSuffix(" mm"); spinbox2_2->setMinimum(10); spinbox2_2->setMaximum(500); spinbox2_2->setValue((int)(3550.0 / (1.0 / mainwindow->x_pixelsizefactor))); ApplyButton = new QPushButton(tab2); ApplyButton->setGeometry(QRect(85, 600, 100, 25)); ApplyButton->setText("Apply"); if(checkbox2_1->checkState() == Qt::Unchecked) { spinbox2_1->setEnabled(FALSE); spinbox2_2->setEnabled(FALSE); ApplyButton->setEnabled(FALSE); } QObject::connect(ApplyButton, SIGNAL(clicked()), this, SLOT(ApplyButtonClicked())); QObject::connect(checkbox2_1, SIGNAL(stateChanged(int)), this, SLOT(calibrate_checkbox_stateChanged(int))); tabholder->addTab(tab2, "Calibration"); /////////////////////////////////////// tab 3 Powerspectrum /////////////////////////////////////////////////////////////////////// tab3 = new QWidget; label1_3 = new QLabel(tab3); label1_3->setGeometry(QRect(20, 20, 330, 25)); label1_3->setText("Frequency regions of the colorbars:"); colorBarTable = new QTableWidget(tab3); colorBarTable->setGeometry(20, 50, 370, 350); colorBarTable->setSelectionMode(QAbstractItemView::NoSelection); colorBarTable->setColumnCount(4); colorBarTable->setColumnWidth(0, 20); colorBarTable->setColumnWidth(1, 140); colorBarTable->setColumnWidth(2, 80); colorBarTable->setColumnWidth(3, 100); colorBarTable->setRowCount(MAXSPECTRUMMARKERS); for(i=0; i < MAXSPECTRUMMARKERS; i++) { colorBarTable->setRowHeight(i, 20); colorBarTable->setCellWidget(i, 0, new QCheckBox); ((QCheckBox *)(colorBarTable->cellWidget(i, 0)))->setTristate(FALSE); if(i < mainwindow->spectrum_colorbar->items) { ((QCheckBox *)(colorBarTable->cellWidget(i, 0)))->setCheckState(Qt::Checked); } else { ((QCheckBox *)(colorBarTable->cellWidget(i, 0)))->setCheckState(Qt::Unchecked); } QObject::connect(colorBarTable->cellWidget(i, 0), SIGNAL(stateChanged(int)), this, SLOT(checkBoxChanged(int))); colorBarTable->setCellWidget(i, 1, new QDoubleSpinBox); ((QDoubleSpinBox *)(colorBarTable->cellWidget(i, 1)))->setDecimals(3); ((QDoubleSpinBox *)(colorBarTable->cellWidget(i, 1)))->setSuffix(" Hz"); ((QDoubleSpinBox *)(colorBarTable->cellWidget(i, 1)))->setRange(0.001, 100000.0); ((QDoubleSpinBox *)(colorBarTable->cellWidget(i, 1)))->setValue(mainwindow->spectrum_colorbar->freq[i]); QObject::connect((QDoubleSpinBox *)(colorBarTable->cellWidget(i, 1)), SIGNAL(valueChanged(double)), this, SLOT(spinBoxValueChanged(double))); colorBarTable->setCellWidget(i, 2, new SpecialButton); ((SpecialButton *)(colorBarTable->cellWidget(i, 2)))->setGlobalColor(mainwindow->spectrum_colorbar->color[i]); QObject::connect((SpecialButton *)(colorBarTable->cellWidget(i, 2)), SIGNAL(clicked(SpecialButton *)), this, SLOT(colorBarButtonClicked(SpecialButton *))); colorBarTable->setCellWidget(i, 3, new QLineEdit); ((QLineEdit *)(colorBarTable->cellWidget(i, 3)))->setText(mainwindow->spectrum_colorbar->label[i]); ((QLineEdit *)(colorBarTable->cellWidget(i, 3)))->setMaxLength(16); QObject::connect((QLineEdit *)(colorBarTable->cellWidget(i, 3)), SIGNAL(textEdited(const QString &)), this, SLOT(labelEdited(const QString &))); } QStringList horizontallabels; horizontallabels += ""; horizontallabels += "Frequency"; horizontallabels += "Color"; horizontallabels += "Label"; colorBarTable->setHorizontalHeaderLabels(horizontallabels); label2_3 = new QLabel(tab3); label2_3->setGeometry(QRect(20, 410, 310, 25)); label2_3->setText("Height of colorbars are relative to the"); radiobutton1 = new QRadioButton(tab3); radiobutton1->setGeometry(QRect(20, 435, 200, 25)); radiobutton1->setText("sum"); if(mainwindow->spectrum_colorbar->method == 0) { radiobutton1->setChecked(TRUE); // sum } radiobutton2 = new QRadioButton(tab3); radiobutton2->setGeometry(QRect(20, 460, 200, 25)); radiobutton2->setText("peak"); if(mainwindow->spectrum_colorbar->method == 1) { radiobutton2->setChecked(TRUE); // peak } radiobutton3 = new QRadioButton(tab3); radiobutton3->setGeometry(QRect(20, 485, 200, 25)); radiobutton3->setText("average"); if(mainwindow->spectrum_colorbar->method == 2) { radiobutton3->setChecked(TRUE); // average } label3_3 = new QLabel(tab3); label3_3->setGeometry(QRect(20, 515, 310, 25)); label3_3->setText("of the power in the colorbar region."); label3_4 = new QLabel(tab3); label3_4->setGeometry(QRect(20, 550, 120, 25)); label3_4->setText("FFT blocksize:"); spinbox3_1 = new QSpinBox(tab3); spinbox3_1->setGeometry(QRect(140, 552, 140, 20)); spinbox3_1->setSuffix(" samples"); spinbox3_1->setMinimum(10); spinbox3_1->setMaximum(32768); spinbox3_1->setSingleStep(2); spinbox3_1->setValue(mainwindow->maxdftblocksize); DefaultButton2 = new QPushButton(tab3); DefaultButton2->setGeometry(QRect(245, 605, 100, 25)); DefaultButton2->setText("Restore default"); ApplyButton2 = new QPushButton(tab3); ApplyButton2->setGeometry(QRect(20, 605, 100, 25)); ApplyButton2->setText("Apply"); ApplyButton2->setEnabled(FALSE); QObject::connect(radiobutton1, SIGNAL(toggled(bool)), this, SLOT(radioButtonToggled(bool))); QObject::connect(radiobutton2, SIGNAL(toggled(bool)), this, SLOT(radioButtonToggled(bool))); QObject::connect(radiobutton3, SIGNAL(toggled(bool)), this, SLOT(radioButtonToggled(bool))); QObject::connect(spinbox3_1, SIGNAL(valueChanged(int)), this, SLOT(spinBox3_3ValueChanged(int))); QObject::connect(ApplyButton2, SIGNAL(clicked()), this, SLOT(ApplyButton2Clicked())); QObject::connect(DefaultButton2, SIGNAL(clicked()), this, SLOT(DefaultButton2Clicked())); tabholder->addTab(tab3, "Powerspectrum"); /////////////////////////////////////// tab 4 Other /////////////////////////////////////////////////////////////////////// tab4 = new QWidget; label4_1 = new QLabel(tab4); label4_1->setGeometry(QRect(20, 20, 280, 25)); label4_1->setText("Reload last used montage"); checkbox4_1 = new QCheckBox(tab4); checkbox4_1->setGeometry(QRect(325, 23, 20, 20)); checkbox4_1->setTristate(FALSE); if(mainwindow->auto_reload_mtg) { checkbox4_1->setCheckState(Qt::Checked); } else { checkbox4_1->setCheckState(Qt::Unchecked); } QObject::connect(checkbox4_1, SIGNAL(stateChanged(int)), this, SLOT(checkbox4_1Clicked(int))); label4_7 = new QLabel(tab4); label4_7->setGeometry(QRect(20, 60, 280, 60)); label4_7->setText("Do not read annotations, Biosemi Status signal\n" "or Nihon Kohden triggers when filesize\n" "is more than:"); spinbox4_3 = new QSpinBox(tab4); spinbox4_3->setGeometry(QRect(200, 100, 140, 20)); spinbox4_3->setSuffix(" MB"); spinbox4_3->setMinimum(100); spinbox4_3->setMaximum(100000); spinbox4_3->setSingleStep(1); spinbox4_3->setValue((int)(mainwindow->maxfilesize_to_readin_annotations / 1048576LL)); QObject::connect(spinbox4_3, SIGNAL(valueChanged(int)), this, SLOT(spinBox4_3ValueChanged(int))); label4_2 = new QLabel(tab4); label4_2->setGeometry(QRect(20, 135, 280, 25)); label4_2->setText("Read Biosemi Status signal"); checkbox4_2 = new QCheckBox(tab4); checkbox4_2->setGeometry(QRect(325, 138, 20, 20)); checkbox4_2->setTristate(FALSE); if(mainwindow->read_biosemi_status_signal) { checkbox4_2->setCheckState(Qt::Checked); } else { checkbox4_2->setCheckState(Qt::Unchecked); } QObject::connect(checkbox4_2, SIGNAL(stateChanged(int)), this, SLOT(checkbox4_2Clicked(int))); label4_6 = new QLabel(tab4); label4_6->setGeometry(QRect(20, 175, 280, 25)); label4_6->setText("Read Nihon Kohden Trigger/Marker signal"); checkbox4_3 = new QCheckBox(tab4); checkbox4_3->setGeometry(QRect(325, 178, 20, 20)); checkbox4_3->setTristate(FALSE); if(mainwindow->read_nk_trigger_signal) { checkbox4_3->setCheckState(Qt::Checked); } else { checkbox4_3->setCheckState(Qt::Unchecked); } QObject::connect(checkbox4_3, SIGNAL(stateChanged(int)), this, SLOT(checkbox4_3Clicked(int))); label4_3 = new QLabel(tab4); label4_3->setGeometry(QRect(20, 215, 200, 25)); label4_3->setText("livestream update interval"); spinbox4_1 = new QSpinBox(tab4); spinbox4_1->setGeometry(QRect(200, 218, 140, 20)); spinbox4_1->setSuffix(" mSec"); spinbox4_1->setMinimum(100); spinbox4_1->setMaximum(3000); spinbox4_1->setSingleStep(1); spinbox4_1->setValue(mainwindow->live_stream_update_interval); QObject::connect(spinbox4_1, SIGNAL(valueChanged(int)), this, SLOT(spinBox4_1ValueChanged(int))); label4_4 = new QLabel(tab4); label4_4->setGeometry(QRect(20, 255, 200, 25)); label4_4->setText("Powerline Frequency"); combobox4_1 = new QComboBox(tab4); combobox4_1->setGeometry(QRect(200, 258, 140, 20)); combobox4_1->addItem("50 Hz"); combobox4_1->addItem("60 Hz"); if(mainwindow->powerlinefreq == 50) { combobox4_1->setCurrentIndex(0); } if(mainwindow->powerlinefreq == 60) { combobox4_1->setCurrentIndex(1); } QObject::connect(combobox4_1, SIGNAL(currentIndexChanged(int)), this, SLOT(combobox4_1IndexChanged(int))); label4_4 = new QLabel(tab4); label4_4->setGeometry(QRect(20, 295, 200, 40)); label4_4->setText("Mousewheel stepsize\n" "(0 is no scroll)"); spinbox4_2 = new QSpinBox(tab4); spinbox4_2->setGeometry(QRect(200, 298, 140, 20)); spinbox4_2->setPrefix("Timescale / "); spinbox4_2->setMinimum(0); spinbox4_2->setMaximum(100); spinbox4_2->setSingleStep(1); spinbox4_2->setValue(mainwindow->mousewheelsens); QObject::connect(spinbox4_2, SIGNAL(valueChanged(int)), this, SLOT(spinBox4_2ValueChanged(int))); label4_5 = new QLabel(tab4); label4_5->setGeometry(QRect(20, 335, 280, 25)); label4_5->setText("Use Multi-Threading"); checkbox4_4 = new QCheckBox(tab4); checkbox4_4->setGeometry(QRect(325, 338, 20, 20)); checkbox4_4->setTristate(FALSE); if(mainwindow->use_threads) { checkbox4_4->setCheckState(Qt::Checked); } else { checkbox4_4->setCheckState(Qt::Unchecked); } QObject::connect(checkbox4_4, SIGNAL(stateChanged(int)), this, SLOT(checkbox4_4Clicked(int))); label4_8 = new QLabel(tab4); label4_8->setGeometry(QRect(20, 375, 310, 25)); label4_8->setText("Check for updates during startup"); checkbox4_5 = new QCheckBox(tab4); checkbox4_5->setGeometry(QRect(325, 378, 20, 20)); checkbox4_5->setTristate(FALSE); if(mainwindow->check_for_updates) { checkbox4_5->setCheckState(Qt::Checked); } else { checkbox4_5->setCheckState(Qt::Unchecked); } QObject::connect(checkbox4_5, SIGNAL(stateChanged(int)), this, SLOT(checkbox4_5Clicked(int))); label4_9 = new QLabel(tab4); label4_9->setGeometry(20, 415, 310, 25); label4_9->setText("Viewtime / fileposition indicator"); combobox4_2 = new QComboBox(tab4); combobox4_2->setGeometry(200, 415, 140, 20); combobox4_2->addItem("relative"); combobox4_2->addItem("real (relative)"); combobox4_2->addItem("date real (relative)"); combobox4_2->setCurrentIndex(mainwindow->viewtime_indicator_type); QObject::connect(combobox4_2, SIGNAL(currentIndexChanged(int)), this, SLOT(combobox4_2IndexChanged(int))); label4_10 = new QLabel(tab4); label4_10->setGeometry(20, 455, 310, 25); label4_10->setText("Window title content"); combobox4_3 = new QComboBox(tab4); combobox4_3->setGeometry(200, 455, 180, 20); combobox4_3->addItem("Subject info"); combobox4_3->addItem("Filename"); combobox4_3->addItem("Filename with full path"); combobox4_3->setCurrentIndex(mainwindow->mainwindow_title_type); QObject::connect(combobox4_3, SIGNAL(currentIndexChanged(int)), this, SLOT(combobox4_3IndexChanged(int))); tabholder->addTab(tab4, "Other"); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// horLayout = new QHBoxLayout; horLayout->addSpacing(300); horLayout->addWidget(CloseButton); mainLayout = new QVBoxLayout; mainLayout->addWidget(tabholder); mainLayout->addLayout(horLayout); if(showminimized) { frame->setLayout(mainLayout); scrollarea->setWidget(frame); scrolllayout = new QGridLayout; scrolllayout->addWidget(scrollarea, 0, 0); optionsdialog->setLayout(scrolllayout); } else { optionsdialog->setLayout(mainLayout); } QObject::connect(CloseButton, SIGNAL(clicked()), optionsdialog, SLOT(close())); optionsdialog->exec(); } void UI_OptionsDialog::spinBox4_3ValueChanged(int filesize) { mainwindow->maxfilesize_to_readin_annotations = (long long)filesize * 1048576LL; } void UI_OptionsDialog::spinBox4_2ValueChanged(int stepsize) { mainwindow->mousewheelsens = stepsize; } void UI_OptionsDialog::combobox4_1IndexChanged(int index) { if(index == 0) { mainwindow->powerlinefreq = 50; } if(index == 1) { mainwindow->powerlinefreq = 60; } } void UI_OptionsDialog::combobox4_2IndexChanged(int index) { mainwindow->viewtime_indicator_type = index; mainwindow->setup_viewbuf(); } void UI_OptionsDialog::combobox4_3IndexChanged(int index) { mainwindow->mainwindow_title_type = index; mainwindow->setMainwindowTitle(mainwindow->edfheaderlist[mainwindow->sel_viewtime]); } void UI_OptionsDialog::spinBox4_1ValueChanged(int interval) { mainwindow->live_stream_update_interval = interval; } void UI_OptionsDialog::calibrate_checkbox_stateChanged(int state) { if(state == Qt::Checked) { spinbox2_1->setEnabled(TRUE); spinbox2_2->setEnabled(TRUE); ApplyButton->setEnabled(TRUE); mainwindow->auto_dpi = 0; } else { spinbox2_1->setEnabled(FALSE); spinbox2_2->setEnabled(FALSE); ApplyButton->setEnabled(FALSE); mainwindow->auto_dpi = 1; mainwindow->pixelsizefactor = 1.0 / ((double)mainwindow->dpiy / 2.54); mainwindow->x_pixelsizefactor = 1.0 / ((double)mainwindow->dpix / 2.54); mainwindow->maincurve->drawCurve_stage_1(); } } void UI_OptionsDialog::ApplyButtonClicked() { int i, j; mainwindow->pixelsizefactor = 1.0 / (4450.0 / spinbox2_1->value()); mainwindow->x_pixelsizefactor = 1.0 / (3550.0 / spinbox2_2->value()); for(i=0; isignalcomps; i++) { for(j=0; jsignalcomp[i]->num_of_signals; j++) { mainwindow->signalcomp[i]->sensitivity[j] = mainwindow->signalcomp[i]->edfhdr->edfparam[mainwindow->signalcomp[i]->edfsignal[j]].bitvalue / ((double)mainwindow->signalcomp[i]->voltpercm * mainwindow->pixelsizefactor); } } mainwindow->maincurve->drawCurve_stage_1(); } void UI_OptionsDialog::labelEdited(const QString &) { ApplyButton2->setEnabled(TRUE); } void UI_OptionsDialog::spinBox3_3ValueChanged(int) { ApplyButton2->setEnabled(TRUE); } void UI_OptionsDialog::radioButtonToggled(bool) { ApplyButton2->setEnabled(TRUE); } void UI_OptionsDialog::spinBoxValueChanged(double) { ApplyButton2->setEnabled(TRUE); } void UI_OptionsDialog::ApplyButton2Clicked() { int row; char str[256]; for(row = 1; row < MAXSPECTRUMMARKERS; row++) { if(((QCheckBox *)(colorBarTable->cellWidget(row, 0)))->checkState() == Qt::Checked) { if(((QDoubleSpinBox *)(colorBarTable->cellWidget(row - 1, 1)))->value() >= ((QDoubleSpinBox *)(colorBarTable->cellWidget(row, 1)))->value()) { sprintf(str, "Row %i must have a higher frequency than row %i", row + 1, row); QMessageBox messagewindow(QMessageBox::Critical, "Error", str); messagewindow.exec(); return; } } else { break; } } for(row = 0; row < MAXSPECTRUMMARKERS; row++) { if(((QCheckBox *)(colorBarTable->cellWidget(row, 0)))->checkState() == Qt::Checked) { mainwindow->spectrum_colorbar->freq[row] = ((QDoubleSpinBox *)(colorBarTable->cellWidget(row, 1)))->value(); mainwindow->spectrum_colorbar->color[row] = ((SpecialButton *)(colorBarTable->cellWidget(row, 2)))->globalColor(); strncpy(mainwindow->spectrum_colorbar->label[row], ((QLineEdit *)(colorBarTable->cellWidget(row, 3)))->text().toLatin1().data(), 16); mainwindow->spectrum_colorbar->label[row][16] = 0; } else { break; } } mainwindow->spectrum_colorbar->items = row; for(; row < MAXSPECTRUMMARKERS; row++) { mainwindow->spectrum_colorbar->freq[row] = ((QDoubleSpinBox *)(colorBarTable->cellWidget(row, 1)))->value(); mainwindow->spectrum_colorbar->color[row] = ((SpecialButton *)(colorBarTable->cellWidget(row, 2)))->globalColor(); } if(radiobutton1->isChecked()) // sum { mainwindow->spectrum_colorbar->method = 0; } else if(radiobutton2->isChecked()) // peak { mainwindow->spectrum_colorbar->method = 1; } else if(radiobutton3->isChecked()) // average { mainwindow->spectrum_colorbar->method = 2; } mainwindow->maxdftblocksize = spinbox3_1->value(); if(mainwindow->maxdftblocksize & 1) { mainwindow->maxdftblocksize--; } ApplyButton2->setEnabled(FALSE); } void UI_OptionsDialog::checkBoxChanged(int state) { int i, row, lastrow=0; if(state == Qt::Checked) { for(row = MAXSPECTRUMMARKERS - 1; row >= 0; row--) { if(((QCheckBox *)(colorBarTable->cellWidget(row, 0)))->checkState() == Qt::Checked) { lastrow = row; if(row) { for(i=row-1; i>=0; i--) { ((QCheckBox *)(colorBarTable->cellWidget(i, 0)))->setCheckState(Qt::Checked); } } break; } } } else { for(row = 0; row < MAXSPECTRUMMARKERS; row++) { if(((QCheckBox *)(colorBarTable->cellWidget(row, 0)))->checkState() == Qt::Unchecked) { lastrow = row - 1; for(; row < MAXSPECTRUMMARKERS; row++) { ((QCheckBox *)(colorBarTable->cellWidget(row, 0)))->setCheckState(Qt::Unchecked); } break; } } } for(row=0; row < lastrow; row++) { if(((QDoubleSpinBox *)(colorBarTable->cellWidget(row, 1)))->value() >= ((QDoubleSpinBox *)(colorBarTable->cellWidget(row + 1, 1)))->value()) { ((QDoubleSpinBox *)(colorBarTable->cellWidget(row + 1, 1)))->setValue(((QDoubleSpinBox *)(colorBarTable->cellWidget(row, 1)))->value() + 1.0); } } ApplyButton2->setEnabled(TRUE); } void UI_OptionsDialog::DefaultButton2Clicked() { int i; for(i=0; i<5; i++) { ((QCheckBox *)(colorBarTable->cellWidget(i, 0)))->setCheckState(Qt::Checked); ((QLineEdit *)(colorBarTable->cellWidget(i, 3)))->clear(); } ((QDoubleSpinBox *)(colorBarTable->cellWidget(0, 1)))->setValue(4.0); ((SpecialButton *)(colorBarTable->cellWidget(0, 2)))->setGlobalColor(Qt::darkRed); ((QDoubleSpinBox *)(colorBarTable->cellWidget(1, 1)))->setValue(8.0); ((SpecialButton *)(colorBarTable->cellWidget(1, 2)))->setGlobalColor(Qt::darkGreen); ((QDoubleSpinBox *)(colorBarTable->cellWidget(2, 1)))->setValue(12.0); ((SpecialButton *)(colorBarTable->cellWidget(2, 2)))->setGlobalColor(Qt::darkBlue); ((QDoubleSpinBox *)(colorBarTable->cellWidget(3, 1)))->setValue(30.0); ((SpecialButton *)(colorBarTable->cellWidget(3, 2)))->setGlobalColor(Qt::darkCyan); ((QDoubleSpinBox *)(colorBarTable->cellWidget(4, 1)))->setValue(100.0); ((SpecialButton *)(colorBarTable->cellWidget(4, 2)))->setGlobalColor(Qt::darkMagenta); for(i=5; icellWidget(i, 0)))->setCheckState(Qt::Unchecked); ((QDoubleSpinBox *)(colorBarTable->cellWidget(i, 1)))->setValue(1.0); ((SpecialButton *)(colorBarTable->cellWidget(i, 2)))->setGlobalColor(Qt::white); ((QLineEdit *)(colorBarTable->cellWidget(i, 3)))->clear(); } spinbox3_1->setValue(1000); radiobutton2->setChecked(TRUE); ApplyButton2->setEnabled(TRUE); } void UI_OptionsDialog::colorBarButtonClicked(SpecialButton *button) { int color; UI_ColorMenuDialog colormenudialog(&color); if(color < 0) return; button->setGlobalColor(color); ApplyButton2->setEnabled(TRUE); } void UI_OptionsDialog::checkbox1Clicked(int state) { if(state==Qt::Checked) { mainwindow->maincurve->blackwhite_printing = 1; } if(state==Qt::Unchecked) { mainwindow->maincurve->blackwhite_printing = 0; } } void UI_OptionsDialog::checkbox2Clicked(int state) { if(state==Qt::Checked) { mainwindow->show_annot_markers = 1; } if(state==Qt::Unchecked) { mainwindow->show_annot_markers = 0; } mainwindow->maincurve->update(); } void UI_OptionsDialog::checkbox3Clicked(int state) { if(state==Qt::Checked) { mainwindow->show_baselines = 1; } if(state==Qt::Unchecked) { mainwindow->show_baselines = 0; } mainwindow->maincurve->update(); } void UI_OptionsDialog::checkbox4Clicked(int state) { if(state==Qt::Checked) { mainwindow->clip_to_pane = 1; } if(state==Qt::Unchecked) { mainwindow->clip_to_pane = 0; } mainwindow->maincurve->update(); } void UI_OptionsDialog::checkbox4_1Clicked(int state) { if(state==Qt::Checked) { mainwindow->auto_reload_mtg = 1; } if(state==Qt::Unchecked) { mainwindow->auto_reload_mtg = 0; } } void UI_OptionsDialog::checkbox4_2Clicked(int state) { if(state==Qt::Checked) { mainwindow->read_biosemi_status_signal = 1; } if(state==Qt::Unchecked) { mainwindow->read_biosemi_status_signal = 0; } } void UI_OptionsDialog::checkbox4_3Clicked(int state) { if(state==Qt::Checked) { mainwindow->read_nk_trigger_signal = 1; } if(state==Qt::Unchecked) { mainwindow->read_nk_trigger_signal = 0; } } void UI_OptionsDialog::checkbox4_4Clicked(int state) { if(state==Qt::Checked) { mainwindow->use_threads = 1; } if(state==Qt::Unchecked) { mainwindow->use_threads = 0; } } void UI_OptionsDialog::checkbox4_5Clicked(int state) { if(state==Qt::Checked) { mainwindow->check_for_updates = 1; } if(state==Qt::Unchecked) { mainwindow->check_for_updates = 0; } } void UI_OptionsDialog::DefaultButtonClicked() { int i; QPalette palette; mainwindow->maincurve->backgroundcolor = Qt::gray; BgColorButton->setColor(mainwindow->maincurve->backgroundcolor); mainwindow->maincurve->small_ruler_color = Qt::black; SrColorButton->setColor(mainwindow->maincurve->small_ruler_color); mainwindow->maincurve->big_ruler_color = Qt::darkGray; BrColorButton->setColor(mainwindow->maincurve->big_ruler_color); mainwindow->maincurve->mouse_rect_color = Qt::black; MrColorButton->setColor(mainwindow->maincurve->mouse_rect_color); mainwindow->maincurve->text_color = Qt::black; TxtColorButton->setColor(mainwindow->maincurve->text_color); mainwindow->maincurve->signal_color = Qt::blue; SigColorButton->setColor(Qt::blue); mainwindow->maincurve->baseline_color = Qt::darkGray; BaseColorButton->setColor(Qt::darkGray); mainwindow->show_baselines = 1; checkbox3->setCheckState(Qt::Checked); mainwindow->maincurve->crosshair_1.color = Qt::red; Crh1ColorButton->setColor(Qt::red); mainwindow->maincurve->crosshair_2.color = Qt::cyan; Crh2ColorButton->setColor(Qt::cyan); mainwindow->maincurve->floating_ruler_color = Qt::red; FrColorButton->setColor(Qt::red); mainwindow->maincurve->annot_marker_color = Qt::white; AnnotMkrButton->setColor(Qt::white); mainwindow->show_annot_markers = 1; checkbox2->setCheckState(Qt::Checked); palette.setColor(QPalette::Text, mainwindow->maincurve->text_color); palette.setColor(QPalette::Base, mainwindow->maincurve->backgroundcolor); for(i=0; ifiles_open; i++) { if(mainwindow->annotations_dock[i]) { mainwindow->annotations_dock[i]->list->setPalette(palette); } } for(i=0; isignalcomps; i++) { mainwindow->signalcomp[i]->color = mainwindow->maincurve->signal_color; } mainwindow->maincurve->blackwhite_printing = 1; checkbox1->setCheckState(Qt::Checked); checkbox4->setCheckState(Qt::Unchecked); mainwindow->maincurve->update(); } void UI_OptionsDialog::BgColorButtonClicked(SpecialButton *) { int i; QColor temp; QPalette palette; temp = QColorDialog::getColor(mainwindow->maincurve->backgroundcolor, tab1); if(temp.isValid()) { mainwindow->maincurve->backgroundcolor = temp; BgColorButton->setColor(mainwindow->maincurve->backgroundcolor); palette.setColor(QPalette::Text, mainwindow->maincurve->text_color); palette.setColor(QPalette::Base, mainwindow->maincurve->backgroundcolor); for(i=0; ifiles_open; i++) { if(mainwindow->annotations_dock[i]) { mainwindow->annotations_dock[i]->list->setPalette(palette); } } mainwindow->maincurve->update(); } } void UI_OptionsDialog::SrColorButtonClicked(SpecialButton *) { QColor temp; temp = QColorDialog::getColor(mainwindow->maincurve->small_ruler_color, tab1); if(temp.isValid()) { mainwindow->maincurve->small_ruler_color = temp; SrColorButton->setColor(mainwindow->maincurve->small_ruler_color); mainwindow->maincurve->update(); } } void UI_OptionsDialog::BrColorButtonClicked(SpecialButton *) { QColor temp; temp = QColorDialog::getColor(mainwindow->maincurve->big_ruler_color, tab1); if(temp.isValid()) { mainwindow->maincurve->big_ruler_color = temp; BrColorButton->setColor(mainwindow->maincurve->big_ruler_color); mainwindow->maincurve->update(); } } void UI_OptionsDialog::MrColorButtonClicked(SpecialButton *) { QColor temp; temp = QColorDialog::getColor(mainwindow->maincurve->mouse_rect_color, tab1); if(temp.isValid()) { mainwindow->maincurve->mouse_rect_color = temp; MrColorButton->setColor(mainwindow->maincurve->mouse_rect_color); mainwindow->maincurve->update(); } } void UI_OptionsDialog::TxtColorButtonClicked(SpecialButton *) { int i; QColor temp; QPalette palette; temp = QColorDialog::getColor(mainwindow->maincurve->text_color, tab1); if(temp.isValid()) { mainwindow->maincurve->text_color = temp; TxtColorButton->setColor(mainwindow->maincurve->text_color); palette.setColor(QPalette::Text, mainwindow->maincurve->text_color); palette.setColor(QPalette::Base, mainwindow->maincurve->backgroundcolor); for(i=0; ifiles_open; i++) { if(mainwindow->annotationlist[i]) { mainwindow->annotations_dock[i]->list->setPalette(palette); } } mainwindow->maincurve->update(); } } void UI_OptionsDialog::SigColorButtonClicked(SpecialButton *) { int i, color; UI_ColorMenuDialog colormenudialog(&color); if(color < 0) return; SigColorButton->setColor((Qt::GlobalColor)color); mainwindow->maincurve->signal_color = color; for(i=0; isignalcomps; i++) { mainwindow->signalcomp[i]->color = color; } mainwindow->maincurve->update(); } void UI_OptionsDialog::BaseColorButtonClicked(SpecialButton *) { QColor temp; temp = QColorDialog::getColor(mainwindow->maincurve->baseline_color, tab1); if(temp.isValid()) { mainwindow->maincurve->baseline_color = temp; BaseColorButton->setColor(mainwindow->maincurve->baseline_color); mainwindow->maincurve->update(); } } void UI_OptionsDialog::Crh1ColorButtonClicked(SpecialButton *) { int color; UI_ColorMenuDialog colormenudialog(&color); if(color < 0) return; Crh1ColorButton->setColor((Qt::GlobalColor)color); mainwindow->maincurve->crosshair_1.color = color; mainwindow->maincurve->update(); } void UI_OptionsDialog::Crh2ColorButtonClicked(SpecialButton *) { int color; UI_ColorMenuDialog colormenudialog(&color); if(color < 0) return; Crh2ColorButton->setColor((Qt::GlobalColor)color); mainwindow->maincurve->crosshair_2.color = color; mainwindow->maincurve->update(); } void UI_OptionsDialog::FrColorButtonClicked(SpecialButton *) { int color; UI_ColorMenuDialog colormenudialog(&color); if(color < 0) return; FrColorButton->setColor((Qt::GlobalColor)color); mainwindow->maincurve->floating_ruler_color = color; mainwindow->maincurve->update(); } void UI_OptionsDialog::AnnotMkrButtonClicked(SpecialButton *) { QColor temp; temp = QColorDialog::getColor(mainwindow->maincurve->annot_marker_color, tab1); if(temp.isValid()) { mainwindow->maincurve->annot_marker_color = temp; AnnotMkrButton->setColor(mainwindow->maincurve->annot_marker_color); mainwindow->maincurve->update(); } } void UI_OptionsDialog::saveColorSchemaButtonClicked() { char path[MAX_PATH_LENGTH]; FILE *colorfile; strcpy(path, mainwindow->recent_colordir); strcat(path, "/my_colorschema.color"); strcpy(path, QFileDialog::getSaveFileName(0, "Save colorschema", QString::fromLocal8Bit(path), "Colorschema files (*.color *.COLOR)").toLocal8Bit().data()); if(!strcmp(path, "")) { return; } if(strlen(path) > 4) { if(strcmp(path + strlen(path) - 6, ".color")) { strcat(path, ".color"); } } get_directory_from_path(mainwindow->recent_colordir, path, MAX_PATH_LENGTH); colorfile = fopen(path, "wb"); if(colorfile==NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not open file for writing."); messagewindow.exec(); return; } fprintf(colorfile, "\n<" PROGRAM_NAME "_colorschema>\n"); fprintf(colorfile, " \n" " %i\n" " %i\n" " %i\n" " \n", mainwindow->maincurve->backgroundcolor.red(), mainwindow->maincurve->backgroundcolor.green(), mainwindow->maincurve->backgroundcolor.blue()); fprintf(colorfile, " \n" " %i\n" " %i\n" " %i\n" " \n", mainwindow->maincurve->small_ruler_color.red(), mainwindow->maincurve->small_ruler_color.green(), mainwindow->maincurve->small_ruler_color.blue()); fprintf(colorfile, " \n" " %i\n" " %i\n" " %i\n" " \n", mainwindow->maincurve->big_ruler_color.red(), mainwindow->maincurve->big_ruler_color.green(), mainwindow->maincurve->big_ruler_color.blue()); fprintf(colorfile, " \n" " %i\n" " %i\n" " %i\n" " \n", mainwindow->maincurve->mouse_rect_color.red(), mainwindow->maincurve->mouse_rect_color.green(), mainwindow->maincurve->mouse_rect_color.blue()); fprintf(colorfile, " \n" " %i\n" " %i\n" " %i\n" " \n", mainwindow->maincurve->text_color.red(), mainwindow->maincurve->text_color.green(), mainwindow->maincurve->text_color.blue()); fprintf(colorfile, " \n" " %i\n" " %i\n" " %i\n" " \n", mainwindow->maincurve->baseline_color.red(), mainwindow->maincurve->baseline_color.green(), mainwindow->maincurve->baseline_color.blue()); fprintf(colorfile, " \n" " %i\n" " %i\n" " %i\n" " \n", mainwindow->maincurve->annot_marker_color.red(), mainwindow->maincurve->annot_marker_color.green(), mainwindow->maincurve->annot_marker_color.blue()); fprintf(colorfile, " %i\n", mainwindow->maincurve->signal_color); fprintf(colorfile, " %i\n", mainwindow->maincurve->crosshair_1.color); fprintf(colorfile, " %i\n", mainwindow->maincurve->crosshair_2.color); fprintf(colorfile, " %i\n", mainwindow->maincurve->floating_ruler_color); fprintf(colorfile, " %i\n", mainwindow->maincurve->blackwhite_printing); fprintf(colorfile, " %i\n", mainwindow->show_annot_markers); fprintf(colorfile, " %i\n", mainwindow->show_baselines); fprintf(colorfile, " %i\n", mainwindow->clip_to_pane); fprintf(colorfile, "\n"); fclose(colorfile); } void UI_OptionsDialog::loadColorSchemaButtonClicked() { char path[MAX_PATH_LENGTH], scratchpad[2048], *result; struct xml_handle *xml_hdl; strcpy(path, QFileDialog::getOpenFileName(0, "Load colorschema", QString::fromLocal8Bit(mainwindow->recent_colordir), "Montage files (*.color *.COLOR)").toLocal8Bit().data()); if(!strcmp(path, "")) { return; } get_directory_from_path(mainwindow->recent_colordir, path, MAX_PATH_LENGTH); xml_hdl = xml_get_handle(path); if(xml_hdl==NULL) { sprintf(scratchpad, "Can not open colorschema:\n%s", path); QMessageBox messagewindow(QMessageBox::Critical, "Error", QString::fromLocal8Bit(scratchpad)); messagewindow.exec(); return; } if(strcmp(xml_hdl->elementname, PROGRAM_NAME "_colorschema")) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "There seems to be an error in this colorschema."); messagewindow.exec(); xml_close(xml_hdl); return; } mainwindow->get_rgbcolor_settings(xml_hdl, "backgroundcolor", 0, &mainwindow->maincurve->backgroundcolor); mainwindow->get_rgbcolor_settings(xml_hdl, "small_ruler_color", 0, &mainwindow->maincurve->small_ruler_color); mainwindow->get_rgbcolor_settings(xml_hdl, "big_ruler_color", 0, &mainwindow->maincurve->big_ruler_color); mainwindow->get_rgbcolor_settings(xml_hdl, "mouse_rect_color", 0, &mainwindow->maincurve->mouse_rect_color); mainwindow->get_rgbcolor_settings(xml_hdl, "text_color", 0, &mainwindow->maincurve->text_color); mainwindow->get_rgbcolor_settings(xml_hdl, "baseline_color", 0, &mainwindow->maincurve->baseline_color); mainwindow->get_rgbcolor_settings(xml_hdl, "annot_marker_color", 0, &mainwindow->maincurve->annot_marker_color); if(xml_goto_nth_element_inside(xml_hdl, "signal_color", 0)) { xml_close(xml_hdl); return; } result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } mainwindow->maincurve->signal_color = atoi(result); free(result); xml_go_up(xml_hdl); if(xml_goto_nth_element_inside(xml_hdl, "floating_ruler_color", 0)) { xml_close(xml_hdl); return; } result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } mainwindow->maincurve->floating_ruler_color = atoi(result); free(result); xml_go_up(xml_hdl); if(xml_goto_nth_element_inside(xml_hdl, "blackwhite_printing", 0)) { xml_close(xml_hdl); return; } result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } mainwindow->maincurve->blackwhite_printing = atoi(result); free(result); xml_go_up(xml_hdl); if(xml_goto_nth_element_inside(xml_hdl, "show_annot_markers", 0)) { xml_close(xml_hdl); return; } result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } mainwindow->show_annot_markers = atoi(result); free(result); xml_go_up(xml_hdl); if(xml_goto_nth_element_inside(xml_hdl, "show_baselines", 0)) { xml_close(xml_hdl); return; } result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } mainwindow->show_baselines = atoi(result); free(result); xml_go_up(xml_hdl); if(xml_goto_nth_element_inside(xml_hdl, "clip_to_pane", 0)) { xml_close(xml_hdl); return; } result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } mainwindow->clip_to_pane = atoi(result); free(result); xml_go_up(xml_hdl); if(xml_goto_nth_element_inside(xml_hdl, "crosshair_1_color", 0)) { xml_close(xml_hdl); return; } result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } mainwindow->maincurve->crosshair_1.color = atoi(result); free(result); xml_go_up(xml_hdl); if(xml_goto_nth_element_inside(xml_hdl, "crosshair_2_color", 0)) { xml_close(xml_hdl); return; } result = xml_get_content_of_element(xml_hdl); if(result==NULL) { xml_close(xml_hdl); return; } mainwindow->maincurve->crosshair_2.color = atoi(result); free(result); xml_close(xml_hdl); update_interface(); } void UI_OptionsDialog::update_interface(void) { int i; QPalette palette; BgColorButton->setColor(mainwindow->maincurve->backgroundcolor); SrColorButton->setColor(mainwindow->maincurve->small_ruler_color); BrColorButton->setColor(mainwindow->maincurve->big_ruler_color); MrColorButton->setColor(mainwindow->maincurve->mouse_rect_color); TxtColorButton->setColor(mainwindow->maincurve->text_color); SigColorButton->setColor((Qt::GlobalColor)mainwindow->maincurve->signal_color); if(mainwindow->show_baselines) { checkbox3->setCheckState(Qt::Checked); } else { checkbox3->setCheckState(Qt::Unchecked); } BaseColorButton->setColor(mainwindow->maincurve->baseline_color); Crh1ColorButton->setColor((Qt::GlobalColor)mainwindow->maincurve->crosshair_1.color); Crh2ColorButton->setColor((Qt::GlobalColor)mainwindow->maincurve->crosshair_2.color); FrColorButton->setColor((Qt::GlobalColor)mainwindow->maincurve->floating_ruler_color); if(mainwindow->show_annot_markers) { checkbox2->setCheckState(Qt::Checked); } else { checkbox2->setCheckState(Qt::Unchecked); } AnnotMkrButton->setColor(mainwindow->maincurve->annot_marker_color); if(mainwindow->maincurve->blackwhite_printing) { checkbox1->setCheckState(Qt::Checked); } else { checkbox1->setCheckState(Qt::Unchecked); } if(mainwindow->clip_to_pane) { checkbox4->setCheckState(Qt::Checked); } else { checkbox4->setCheckState(Qt::Unchecked); } palette.setColor(QPalette::Text, mainwindow->maincurve->text_color); palette.setColor(QPalette::Base, mainwindow->maincurve->backgroundcolor); for(i=0; ifiles_open; i++) { if(mainwindow->annotations_dock[i]) { mainwindow->annotations_dock[i]->list->setPalette(palette); } } for(i=0; isignalcomps; i++) { mainwindow->signalcomp[i]->color = mainwindow->maincurve->signal_color; } mainwindow->maincurve->update(); } void UI_OptionsDialog::loadColorSchema_NK() { mainwindow->maincurve->backgroundcolor.setRed(255); mainwindow->maincurve->backgroundcolor.setGreen(255); mainwindow->maincurve->backgroundcolor.setBlue(255); mainwindow->maincurve->small_ruler_color.setRed(0); mainwindow->maincurve->small_ruler_color.setGreen(0); mainwindow->maincurve->small_ruler_color.setBlue(0); mainwindow->maincurve->big_ruler_color.setRed(255); mainwindow->maincurve->big_ruler_color.setGreen(255); mainwindow->maincurve->big_ruler_color.setBlue(0); mainwindow->maincurve->mouse_rect_color.setRed(0); mainwindow->maincurve->mouse_rect_color.setGreen(0); mainwindow->maincurve->mouse_rect_color.setBlue(0); mainwindow->maincurve->text_color.setRed(0); mainwindow->maincurve->text_color.setGreen(0); mainwindow->maincurve->text_color.setBlue(0); mainwindow->maincurve->baseline_color.setRed(128); mainwindow->maincurve->baseline_color.setGreen(128); mainwindow->maincurve->baseline_color.setBlue(128); mainwindow->maincurve->annot_marker_color.setRed(0); mainwindow->maincurve->annot_marker_color.setGreen(0); mainwindow->maincurve->annot_marker_color.setBlue(0); mainwindow->maincurve->signal_color = 2; mainwindow->maincurve->floating_ruler_color = 7; mainwindow->maincurve->blackwhite_printing = 1; mainwindow->show_annot_markers = 1; mainwindow->show_baselines = 1; mainwindow->maincurve->crosshair_1.color = 7; mainwindow->maincurve->crosshair_2.color = 9; mainwindow->clip_to_pane = 0; update_interface(); } void UI_OptionsDialog::loadColorSchema_Dark() { mainwindow->maincurve->backgroundcolor.setRed(64); mainwindow->maincurve->backgroundcolor.setGreen(64); mainwindow->maincurve->backgroundcolor.setBlue(64); mainwindow->maincurve->small_ruler_color.setRed(255); mainwindow->maincurve->small_ruler_color.setGreen(255); mainwindow->maincurve->small_ruler_color.setBlue(255); mainwindow->maincurve->big_ruler_color.setRed(128); mainwindow->maincurve->big_ruler_color.setGreen(128); mainwindow->maincurve->big_ruler_color.setBlue(128); mainwindow->maincurve->mouse_rect_color.setRed(255); mainwindow->maincurve->mouse_rect_color.setGreen(255); mainwindow->maincurve->mouse_rect_color.setBlue(255); mainwindow->maincurve->text_color.setRed(255); mainwindow->maincurve->text_color.setGreen(255); mainwindow->maincurve->text_color.setBlue(255); mainwindow->maincurve->baseline_color.setRed(128); mainwindow->maincurve->baseline_color.setGreen(128); mainwindow->maincurve->baseline_color.setBlue(128); mainwindow->maincurve->annot_marker_color.setRed(255); mainwindow->maincurve->annot_marker_color.setGreen(255); mainwindow->maincurve->annot_marker_color.setBlue(255); mainwindow->maincurve->signal_color = 12; mainwindow->maincurve->floating_ruler_color = 10; mainwindow->maincurve->blackwhite_printing = 1; mainwindow->show_annot_markers = 1; mainwindow->show_baselines = 1; mainwindow->maincurve->crosshair_1.color = 7; mainwindow->maincurve->crosshair_2.color = 10; mainwindow->clip_to_pane = 0; update_interface(); } edfbrowser_153_source/PaxHeaders.2978/edit_annotation_dock.h0000644000175000001440000000013212251654530022477 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/edit_annotation_dock.h0000644000175000001440000000524012251654530022231 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef ANNOTATION_EDIT_FORM1_H #define ANNOTATION_EDIT_FORM1_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "mainwindow.h" #include "annotations_dock.h" #include "popup_save_cancelwindow.h" #include "edf_annot_list.h" class UI_Mainwindow; class UI_AnnotationEditwindow : public QObject { Q_OBJECT public: UI_AnnotationEditwindow(int, QWidget *parent); UI_Mainwindow *mainwindow; QDockWidget *dockedit; void annotEditSetOnset(long long); void annotEditSetDuration(long long); void set_selected_annotation(int, int); void set_selected_annotation(struct annotationblock *); private: struct annotationblock *annotation; int file_num, annot_num; QDialog *annot_edit_dialog; QLabel *onsetLabel, *durationLabel, *descriptionLabel; QLineEdit *annot_descript_lineEdit; QTimeEdit *onset_timeEdit; QSpinBox *onset_daySpinbox; QDoubleSpinBox *duration_spinbox; QPushButton *modifybutton, *deletebutton, *createbutton; QComboBox *posNegTimebox; private slots: void modifyButtonClicked(); void deleteButtonClicked(); void createButtonClicked(); void open_close_dock(bool); }; #endif edfbrowser_153_source/PaxHeaders.2978/scp_ecg2edf.cpp0000644000175000001440000000013212251654530021017 xustar000000000000000030 mtime=1386699096.479032511 30 atime=1386699096.479032511 30 ctime=1386699096.479032511 edfbrowser_153_source/scp_ecg2edf.cpp0000644000175000001440000010740112251654530020553 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "scp_ecg2edf.h" #if defined(__APPLE__) || defined(__MACH__) || defined(__APPLE_CC__) #define fopeno fopen #else #define fseeko fseeko64 #define ftello ftello64 #define fopeno fopen64 #endif #define SPCECGBUFSIZE 1048576 UI_SCPECG2EDFwindow::UI_SCPECG2EDFwindow(char *recent_dir, char *save_dir) { char txt_string[2048]; recent_opendir = recent_dir; recent_savedir = save_dir; myobjectDialog = new QDialog; myobjectDialog->setMinimumSize(QSize(600, 480)); myobjectDialog->setMaximumSize(QSize(600, 480)); myobjectDialog->setWindowTitle("SCP ECG to EDF+ converter"); myobjectDialog->setModal(TRUE); myobjectDialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); pushButton1 = new QPushButton(myobjectDialog); pushButton1->setGeometry(QRect(20, 430, 100, 26)); pushButton1->setText("Select File"); pushButton2 = new QPushButton(myobjectDialog); pushButton2->setGeometry(QRect(480, 430, 100, 26)); pushButton2->setText("Close"); textEdit1 = new QTextEdit(myobjectDialog); textEdit1->setGeometry(QRect(20, 20, 560, 380)); textEdit1->setFrameStyle(QFrame::Panel | QFrame::Sunken); textEdit1->setReadOnly(TRUE); textEdit1->setLineWrapMode(QTextEdit::NoWrap); sprintf(txt_string, "SCP ECG to EDF+ converter.\n"); textEdit1->append(txt_string); crc_ccitt_init(); QObject::connect(pushButton1, SIGNAL(clicked()), this, SLOT(SelectFileButton())); QObject::connect(pushButton2, SIGNAL(clicked()), myobjectDialog, SLOT(close())); myobjectDialog->exec(); } void UI_SCPECG2EDFwindow::SelectFileButton() { FILE *inputfile=NULL; int i, j, k, n, hdl, chns, sf, avm, blocks, *buf, encoding, compression, offset, abs_val_a[256], abs_val_b[256], var_tmp; unsigned short sh_tmp; long long filesize, ll_tmp, bits; char input_filename[MAX_PATH_LENGTH], txt_string[2048], edf_filename[MAX_PATH_LENGTH], scratchpad[MAX_PATH_LENGTH], *block, ch_tmp; union{ unsigned long long ll_int; unsigned int one[2]; unsigned short two[4]; unsigned char four[8]; } var; pushButton1->setEnabled(FALSE); for(i=0; i<256; i++) { abs_val_a[i] = 0; abs_val_b[i] = 0; } strcpy(input_filename, QFileDialog::getOpenFileName(0, "Select inputfile", QString::fromLocal8Bit(recent_opendir), "SCP files (*.scp *.SCP)").toLocal8Bit().data()); if(!strcmp(input_filename, "")) { pushButton1->setEnabled(TRUE); return; } get_directory_from_path(recent_opendir, input_filename, MAX_PATH_LENGTH); inputfile = fopeno(input_filename, "rb"); if(inputfile==NULL) { snprintf(txt_string, 2048, "Can not open file %s for reading.\n", input_filename); textEdit1->append(QString::fromLocal8Bit(txt_string)); pushButton1->setEnabled(TRUE); return; } get_filename_from_path(scratchpad, input_filename, MAX_PATH_LENGTH); snprintf(txt_string, 2048, "Read file: %s", scratchpad); textEdit1->append(QString::fromLocal8Bit(txt_string)); fseeko(inputfile, 0LL, SEEK_END); filesize = ftello(inputfile); if(filesize<126) { textEdit1->append("Error, filesize is too small.\n"); fclose(inputfile); pushButton1->setEnabled(TRUE); return; } ll_tmp = 0LL; fseeko(inputfile, 2LL, SEEK_SET); if(fread(&ll_tmp, 4, 1, inputfile) != 1) { textEdit1->append("A read-error occurred (1)\n"); fclose(inputfile); pushButton1->setEnabled(TRUE); return; } if(ll_tmp != filesize) { textEdit1->append("Error, filesize does not match with header.\n"); fclose(inputfile); pushButton1->setEnabled(TRUE); return; } block = (char *)malloc(SPCECGBUFSIZE); if(block == NULL) { textEdit1->append("Malloc error (block 1)\n"); fclose(inputfile); pushButton1->setEnabled(TRUE); return; } rewind(inputfile); if(fread(&sh_tmp, 2, 1, inputfile) != 1) { textEdit1->append("A read-error occurred (2)\n"); fclose(inputfile); free(block); pushButton1->setEnabled(TRUE); return; } if(check_crc(inputfile, 2LL, filesize - 2LL, sh_tmp, block)) { fclose(inputfile); free(block); pushButton1->setEnabled(TRUE); return; } memset(&sp, 0, sizeof(struct section_prop_struct[12])); if(read_section_header(0, inputfile, 6LL, block)) { fclose(inputfile); free(block); pushButton1->setEnabled(TRUE); return; } if(strncmp(sp[0].reserved, "SCPECG", 6)) { textEdit1->append("Error, reserved field of section header 0 does not contain string \"SCPECG\".\n"); fclose(inputfile); free(block); pushButton1->setEnabled(TRUE); return; } sp[0].file_offset = 6LL; // printf("\nsection ID is %i\n" // "section file offset is %lli\n" // "section CRC is 0x%04X\n" // "section length is %i\n" // "section version is %i\n" // "section protocol version is %i\n", // sp[0].section_id, // sp[0].file_offset, // (int)sp[0].crc, // sp[0].section_length, // sp[0].section_version, // sp[0].section_protocol_version); if(read_data_section_zero(inputfile, block, filesize)) { fclose(inputfile); free(block); pushButton1->setEnabled(TRUE); return; } fseeko(inputfile, sp[6].file_offset + 16LL, SEEK_SET); if(fread(block, 6, 1, inputfile) != 1) { textEdit1->append("A read-error occurred\n"); fclose(inputfile); free(block); pushButton1->setEnabled(TRUE); return; } avm = *((unsigned short *)block); sf = 1000000 / *((unsigned short *)(block + 2)); encoding = *((unsigned char *)(block + 4)); compression = *((unsigned char *)(block + 5)); if(compression != 0) { textEdit1->append("File contains bimodal compressed data which is not supported by this converter.\n "); fclose(inputfile); free(block); pushButton1->setEnabled(TRUE); return; } fseeko(inputfile, sp[3].file_offset + 16LL, SEEK_SET); if(fread(scratchpad, 2, 1, inputfile) != 1) { textEdit1->append("A read-error occurred (40)\n"); fclose(inputfile); free(block); pushButton1->setEnabled(TRUE); return; } chns = *((unsigned char *)scratchpad); if(chns < 1) { textEdit1->append("Error, number of signals is less than one.\n "); fclose(inputfile); free(block); pushButton1->setEnabled(TRUE); return; } if(chns > 256) { textEdit1->append("Error, number of signals is more than 256.\n "); fclose(inputfile); free(block); pushButton1->setEnabled(TRUE); return; } if(scratchpad[1] & 1) { textEdit1->append("Reference beat subtraction used for compression which is not supported by this converter.\n "); fclose(inputfile); free(block); pushButton1->setEnabled(TRUE); return; } if(!(scratchpad[1] & 4)) { textEdit1->append("Leads are not simultaneously recorded which is not supported by this converter. (1)\n "); fclose(inputfile); free(block); pushButton1->setEnabled(TRUE); return; } // printf("chns is %u AVM is %u sf is %u encoding is %u compression is %u\n", // chns, avm, sf, encoding, compression); memset(&lp, 0, sizeof(struct lead_prop_struct[256])); fseeko(inputfile, sp[3].file_offset + 18LL, SEEK_SET); for(i=0; iappend("A read-error occurred (30)\n"); fclose(inputfile); free(block); pushButton1->setEnabled(TRUE); return; } if(fread(&(lp[i].end), 4, 1, inputfile) != 1) { textEdit1->append("A read-error occurred (31)\n"); fclose(inputfile); free(block); pushButton1->setEnabled(TRUE); return; } if(fread(&(lp[i].label), 1, 1, inputfile) != 1) { textEdit1->append("A read-error occurred (32)\n"); fclose(inputfile); free(block); pushButton1->setEnabled(TRUE); return; } } // for(i=0; i 1) { for(i=1; iappend("Error, leads are not simultaneously recorded. (2)\n"); fclose(inputfile); free(block); pushButton1->setEnabled(TRUE); return; } if(lp[i].end != lp[0].end) { textEdit1->append("Error, leads are not simultaneously recorded. (3)\n"); fclose(inputfile); free(block); pushButton1->setEnabled(TRUE); return; } } } for(i=0; iappend("Error, start sample number in section 3 is less than 1.\n"); fclose(inputfile); free(block); pushButton1->setEnabled(TRUE); return; } if(lp[i].end <= lp[i].start) { textEdit1->append("Error (56) (lp[i].end <= lp[i].start)\n"); fclose(inputfile); free(block); pushButton1->setEnabled(TRUE); return; } if(lp[i].start != 1) { textEdit1->append("Error (57) (lp[i].start != 1)\n"); fclose(inputfile); free(block); pushButton1->setEnabled(TRUE); return; } lp[i].start--; if((lp[i].end - lp[i].start) < sf) { textEdit1->append("Error, recording length is less than one second.\n"); fclose(inputfile); free(block); pushButton1->setEnabled(TRUE); return; } lp[i].samples = lp[i].end - lp[i].start; } fseeko(inputfile, sp[6].file_offset + 22LL, SEEK_SET); n = 0; for(i=0; iappend("A read-error occurred (41)\n"); fclose(inputfile); free(block); pushButton1->setEnabled(TRUE); return; } lp[i].bytes = *((unsigned short *)block); n += lp[i].bytes; // printf("lead samples is %i bytes is %i\n", lp[i].samples, lp[i].bytes); if(sp[2].present != 1) // huffmantable { if(lp[i].bytes < (lp[i].samples * 2)) { textEdit1->append("Error, lead samples is less than lead bytes.\n"); fclose(inputfile); free(block); pushButton1->setEnabled(TRUE); return; } } } if(n > (sp[6].section_length - 22 - (chns * 2))) { textEdit1->append("Error, total databytes is more than section size.\n"); fclose(inputfile); free(block); pushButton1->setEnabled(TRUE); return; } //////////////////////////////// Huffman tables //////////////////// if(sp[2].present == 1) // huffmantable { fseeko(inputfile, sp[2].file_offset + 16LL, SEEK_SET); if(fread(block, 13, 1, inputfile) != 1) { textEdit1->append("A read-error occurred (50)\n"); fclose(inputfile); free(block); pushButton1->setEnabled(TRUE); return; } ht.h_tables_cnt = *((unsigned short *)block); ht.code_structs_cnt = *((unsigned short *)(block + 2)); ht.prefix_bits = *((unsigned char *)(block + 4)); ht.total_bits = *((unsigned char *)(block + 5)); ht.table_mode_switch = *((unsigned char *)(block + 6)); ht.base_value = *((unsigned short *)(block + 7)); ht.base_code = *((unsigned int *)(block + 9)); // printf("ht.h_tables_cnt is %i ht.code_structs_cnt is %i ht.prefix_bits is %i ht.total_bits is %i\n", // ht.h_tables_cnt, ht.code_structs_cnt, ht.prefix_bits, ht.total_bits); if(ht.h_tables_cnt != 19999) { textEdit1->append("Aborted, this converter does not support customized Huffmantables.\n"); fclose(inputfile); free(block); pushButton1->setEnabled(TRUE); return; } } //////////////////////////////// patient data //////////////////// memset(&pat_dat, 0, sizeof(struct patient_data_struct)); if(get_patient_data(inputfile)) { fclose(inputfile); free(block); pushButton1->setEnabled(TRUE); return; } // printf("patient ID: %s\n" // "patient lastname: %s\n" // "patient firstname: %s\n" // "patient sex: %i\n" // "startdate year: %i\n" // "startdate month: %i\n" // "startdate day: %i\n" // "starttime hour: %i\n" // "starttime minute: %i\n" // "starttime second: %i\n" // "birthdate year: %i\n" // "birthdate month: %i\n" // "birthdate day: %i\n" // "device model: %s\n" // "language code: %u\n" // "manufacturer: %s\n", // pat_dat.pat_id, // pat_dat.last_name, // pat_dat.first_name, // pat_dat.sex, // pat_dat.startdate_year, // pat_dat.startdate_month, // pat_dat.startdate_day, // pat_dat.starttime_hour, // pat_dat.starttime_minute, // pat_dat.starttime_second, // pat_dat.birthdate_year, // pat_dat.birthdate_month, // pat_dat.birthdate_day, // pat_dat.device_model, // pat_dat.lang_code, // pat_dat.manufacturer); ////////////////////////// start conversion /////////////////////////////// free(block); buf = (int *)malloc(((lp[0].samples / sf) + 1) * chns * sf * sizeof(int)); if(buf == NULL) { textEdit1->append("Malloc error (buf)\n"); fclose(inputfile); pushButton1->setEnabled(TRUE); return; } n = 0; for(i=0; iappend("Malloc error (block 3)\n"); fclose(inputfile); free(buf); pushButton1->setEnabled(TRUE); return; } fseeko(inputfile, sp[6].file_offset + 22LL + (chns * 2LL), SEEK_SET); // rhythm data if(fread(block, n, 1, inputfile) != 1) { textEdit1->append("A read-error occurred during conversion (70)\n"); fclose(inputfile); free(buf); free(block); pushButton1->setEnabled(TRUE); return; } offset = 0; for(j=0; j 0) { offset += lp[j - 1].bytes; } bits = 0LL; for(i=0; i lp[j].bytes) { textEdit1->append("Error, (bits / 8) >= lp[j].bytes (71)\n"); fclose(inputfile); free(buf); free(block); pushButton1->setEnabled(TRUE); return; } memcpy(&var, block + offset + ((int)(bits / 8LL)), 5); for(k=0; k<5; k++) { var.four[k] = reverse_bitorder(var.four[k]); } var.ll_int >>= (int)(bits % 8LL); if((var.four[0] & 1) == 0) // b00000001 { buf[((i / sf) * (sf * chns)) + (j * sf) + (i % sf)] = 0; bits++; } else if((var.four[0] & 7) == 1) // b00000111 { buf[((i / sf) * (sf * chns)) + (j * sf) + (i % sf)] = 1; bits += 3LL; } else if((var.four[0] & 7) == 5) // b00000111 { buf[((i / sf) * (sf * chns)) + (j * sf) + (i % sf)] = -1; bits += 3LL; } else if((var.four[0] & 15) == 3) // b00001111 { buf[((i / sf) * (sf * chns)) + (j * sf) + (i % sf)] = 2; bits += 4LL; } else if((var.four[0] & 15) == 11) // b00001111 { buf[((i / sf) * (sf * chns)) + (j * sf) + (i % sf)] = -2; bits += 4LL; } else if((var.four[0] & 31) == 7) // b00011111 { buf[((i / sf) * (sf * chns)) + (j * sf) + (i % sf)] = 3; bits += 5LL; } else if((var.four[0] & 31) == 23) // b00011111 { buf[((i / sf) * (sf * chns)) + (j * sf) + (i % sf)] = -3; bits += 5LL; } else if((var.four[0] & 63) == 15) // b00111111 { buf[((i / sf) * (sf * chns)) + (j * sf) + (i % sf)] = 4; bits += 6LL; } else if((var.four[0] & 63) == 47) // b00111111 { buf[((i / sf) * (sf * chns)) + (j * sf) + (i % sf)] = -4; bits += 6LL; } else if((var.four[0] & 127) == 31) // b01111111 { buf[((i / sf) * (sf * chns)) + (j * sf) + (i % sf)] = 5; bits += 7LL; } else if((var.four[0] & 127) == 95) // b01111111 { buf[((i / sf) * (sf * chns)) + (j * sf) + (i % sf)] = -5; bits += 7LL; } else if(var.four[0] == 63) // b11111111 { buf[((i / sf) * (sf * chns)) + (j * sf) + (i % sf)] = 6; bits += 8LL; } else if(var.four[0] == 191) // b11111111 { buf[((i / sf) * (sf * chns)) + (j * sf) + (i % sf)] = -6; bits += 8LL; } else if(var.four[0] == 127) // b11111111 { if((var.four[1] & 1) == 0) // b00000001 { buf[((i / sf) * (sf * chns)) + (j * sf) + (i % sf)] = 7; bits += 9LL; } else { buf[((i / sf) * (sf * chns)) + (j * sf) + (i % sf)] = -7; bits += 9LL; } } else if(var.four[0] == 255) // b11111111 { if((var.four[1] & 3) == 0) // b00000011 { buf[((i / sf) * (sf * chns)) + (j * sf) + (i % sf)] = 8; bits += 10LL; } else if((var.four[1] & 3) == 2) // b00000011 { buf[((i / sf) * (sf * chns)) + (j * sf) + (i % sf)] = -8; bits += 10LL; } else if((var.four[1] & 3) == 1) // b00000011 { var.ll_int >>= 2; var.four[1] = reverse_bitorder(var.four[1]); buf[((i / sf) * (sf * chns)) + (j * sf) + (i % sf)] = *((signed char *)&(var.four[1])); // 8-bit original bits += 18LL; } else if((var.four[1] & 3) == 3) // b00000011 { var.ll_int >>= 10; ch_tmp = reverse_bitorder(var.four[0]); var.four[0] = reverse_bitorder(var.four[1]); var.four[1] = ch_tmp; buf[((i / sf) * (sf * chns)) + (j * sf) + (i % sf)] = *((signed short *)&(var.two[0])); // 16-bit original bits += 26LL; } } } else // huffmantable not present { buf[((i / sf) * (sf * chns)) + (j * sf) + (i % sf)] = ((signed short *)(block + offset))[i]; } } } strcpy(edf_filename, input_filename); remove_extension_from_filename(edf_filename); strcat(edf_filename, ".edf"); hdl = edfopen_file_writeonly(edf_filename, EDFLIB_FILETYPE_EDFPLUS, chns); if(hdl<0) { snprintf(txt_string, 2048, "Can not open file %s for writing.\n", edf_filename); textEdit1->append(txt_string); fclose(inputfile); free(buf); free(block); pushButton1->setEnabled(TRUE); return; } for(i=0; iappend("Error: edf_set_samplefrequency()\n"); fclose(inputfile); edfclose_file(hdl); free(buf); free(block); pushButton1->setEnabled(TRUE); return; } if(edf_set_digital_minimum(hdl, i, -32768)) { textEdit1->append("Error: edf_set_digital_minimum()\n"); fclose(inputfile); edfclose_file(hdl); free(buf); free(block); pushButton1->setEnabled(TRUE); return; } if(edf_set_digital_maximum(hdl, i, 32767)) { textEdit1->append("Error: edf_set_digital_maximum()\n"); fclose(inputfile); edfclose_file(hdl); free(buf); free(block); pushButton1->setEnabled(TRUE); return; } lead_label_lookup(lp[i].label, scratchpad); if(edf_set_label(hdl, i, scratchpad)) { textEdit1->append("Error: edf_set_label()\n"); fclose(inputfile); edfclose_file(hdl); free(buf); free(block); pushButton1->setEnabled(TRUE); return; } if(edf_set_physical_dimension(hdl, i, "uV")) { textEdit1->append("Error: edf_set_physical_dimension()\n"); fclose(inputfile); edfclose_file(hdl); free(buf); free(block); pushButton1->setEnabled(TRUE); return; } if(edf_set_physical_maximum(hdl, i, 32.767 * (double)avm)) { textEdit1->append("Error: edf_set_physical_maximum()\n"); fclose(inputfile); edfclose_file(hdl); free(buf); free(block); pushButton1->setEnabled(TRUE); return; } if(edf_set_physical_minimum(hdl, i, -32.768 * (double)avm)) { textEdit1->append("Error: edf_set_physical_minimum()\n"); fclose(inputfile); edfclose_file(hdl); free(buf); free(block); pushButton1->setEnabled(TRUE); return; } } strcpy(scratchpad, pat_dat.first_name); strcat(scratchpad, " "); strcat(scratchpad, pat_dat.last_name); remove_trailing_spaces(scratchpad); if(edf_set_patientname(hdl, scratchpad)) { textEdit1->append("Error: edf_set_patientname()\n"); fclose(inputfile); edfclose_file(hdl); free(buf); free(block); pushButton1->setEnabled(TRUE); return; } edf_set_startdatetime(hdl, pat_dat.startdate_year, pat_dat.startdate_month, pat_dat.startdate_day, pat_dat.starttime_hour, pat_dat.starttime_minute, pat_dat.starttime_second); edf_set_birthdate(hdl, pat_dat.birthdate_year, pat_dat.birthdate_month, pat_dat.birthdate_day); if(pat_dat.sex == 1) { edf_set_gender(hdl, 1); } if(pat_dat.sex == 2) { edf_set_gender(hdl, 0); } edf_set_patientcode(hdl, pat_dat.pat_id); strcpy(scratchpad, pat_dat.device_model); strcat(scratchpad, " "); strcat(scratchpad, pat_dat.device_ident); edf_set_equipment(hdl, scratchpad); strcpy(scratchpad, pat_dat.manufacturer); strcat(scratchpad, " "); strcat(scratchpad, pat_dat.device_serial); edf_set_recording_additional(hdl, scratchpad); blocks = lp[0].samples / sf; for(i=0; iappend("A write error occurred during conversion (EDFlib).\n"); fclose(inputfile); edfclose_file(hdl); free(buf); free(block); pushButton1->setEnabled(TRUE); return; } } edfclose_file(hdl); free(buf); free(block); fclose(inputfile); textEdit1->append("Done.\n"); pushButton1->setEnabled(TRUE); } int UI_SCPECG2EDFwindow::read_data_section_zero(FILE *inputfile, char *block, long long filesize) { int i; for(i=1; i<12; i++) { fseeko(inputfile, sp[0].file_offset + 16LL + (i * 10LL), SEEK_SET); if(fread(&(sp[i].section_id), 2, 1, inputfile) != 1) { textEdit1->append("A read-error occurred (20)\n"); return(-1); } if(sp[i].section_id != i) { textEdit1->append("Error, section ID nr does not match\n"); return(-1); } if(fread(&(sp[i].section_length), 4, 1, inputfile) != 1) { textEdit1->append("A read-error occurred (21)\n"); return(-1); } if(fread(&(sp[i].file_offset), 4, 1, inputfile) != 1) { textEdit1->append("A read-error occurred (22)\n"); return(-1); } if((sp[i].section_length > 0) && (sp[i].file_offset > 0LL)) { sp[i].present = 1; sp[i].file_offset--; } else { if((sp[i].section_id == 1) || (sp[i].section_id == 3) || (sp[i].section_id == 6)) { textEdit1->append("Error, a required section is missing\n"); return(-1); } } if((sp[i].file_offset + sp[i].section_length) > filesize) { textEdit1->append("Error, index + length of section is > filesize\n"); return(-1); } if(sp[i].present == 1) { if(read_section_header(i, inputfile, sp[i].file_offset, block)) { return(-1); } } } return(0); } int UI_SCPECG2EDFwindow::check_crc(FILE *inputfile, long long offset, long long len, unsigned short crc2, char *block) { int i, blocks; unsigned short crc = 0xFFFF; long long ll_tmp; blocks = len / SPCECGBUFSIZE; fseeko(inputfile, offset, SEEK_SET); for(i=0; iappend("A read-error occurred (3)\n"); return(-1); } crc = crc_ccitt((unsigned char *)block, SPCECGBUFSIZE, crc); } ll_tmp = len % SPCECGBUFSIZE; if(ll_tmp > 0LL) { if(fread(block, ll_tmp, 1, inputfile) != 1) { textEdit1->append("A read-error occurred (4)\n"); return(-1); } crc = crc_ccitt((unsigned char *)block, ll_tmp, crc); } if(crc != crc2) { textEdit1->append("CRC check failed!\n"); return(-1); } return(0); } int UI_SCPECG2EDFwindow::read_section_header(int n, FILE *inputfile, long long offset, char *block) { char str[256]; fseeko(inputfile, offset, SEEK_SET); if(fread(&(sp[n].crc), 2, 1, inputfile) != 1) { textEdit1->append("A read-error occurred (5)\n"); return(-1); } if(fread(&(sp[n].section_id), 2, 1, inputfile) != 1) { textEdit1->append("A read-error occurred (6)\n"); return(-1); } if(sp[n].section_id != n) { textEdit1->append("Error, section ID does not match"); return(-1); } if(fread(&(sp[n].section_length), 4, 1, inputfile) != 1) { textEdit1->append("A read-error occurred (7)\n"); return(-1); } if(fread(&(sp[n].section_version), 1, 1, inputfile) != 1) { textEdit1->append("A read-error occurred (8)\n"); return(-1); } if(fread(&(sp[n].section_protocol_version), 1, 1, inputfile) != 1) { textEdit1->append("A read-error occurred (9)\n"); return(-1); } if(fread(&(sp[n].reserved), 6, 1, inputfile) != 1) { textEdit1->append("A read-error occurred (10)\n"); return(-1); } if(check_crc(inputfile, offset + 2, sp[n].section_length - 2LL, sp[n].crc, block)) { sprintf(str, "CRC-error in section %i\n", n); textEdit1->append(str); return(-1); } sp[n].present = 1; return(0); } unsigned short UI_SCPECG2EDFwindow::crc_ccitt(const unsigned char *message, int nbytes, unsigned short remainder) { int byte; unsigned char data; for(byte=0; byte> 8); remainder = crc_ccitt_table[data] ^ (remainder << 8); } return(remainder); /* The final remainder is the CRC. */ } void UI_SCPECG2EDFwindow::crc_ccitt_init(void) { int dividend; unsigned short remainder; unsigned char bit; for(dividend=0; dividend<256; dividend++) /* Compute the remainder of each possible dividend. */ { remainder = dividend << 8; /* Start with the dividend followed by zeros. */ for(bit=8; bit>0; bit--) /* Perform modulo-2 division, a bit at a time. */ { if(remainder & 32768) /* Try to divide the current data bit. */ { remainder = (remainder << 1) ^ 0x1021; /* polynomial */ } else { remainder = (remainder << 1); } } crc_ccitt_table[dividend] = remainder; /* Store the result into the table. */ } } inline unsigned char UI_SCPECG2EDFwindow::reverse_bitorder(unsigned char byte) { byte = (byte & 0xF0) >> 4 | (byte & 0x0F) << 4; byte = (byte & 0xCC) >> 2 | (byte & 0x33) << 2; byte = (byte & 0xAA) >> 1 | (byte & 0x55) << 1; return byte; } void UI_SCPECG2EDFwindow::lead_label_lookup(unsigned char idx, char *label) { char scp_labels[256][9]={"unspec.", "I", "II", "V1", "V2", "V3", "V4", "V5", "V6", "V7", "V2R", "V3R", "V4R", "V5R", "V6R", "V7R", "X", "Y", "Z", "CC5", "CM5", "LA", "RA", "LL", "fl", "fE", "fC", "fA", "fM", "fF", "fH", "dl", "dll", "dV1", "dV2", "dV3", "dV4", "dV5", "dV6", "dV7", "dV2R", "dV3R", "dV4R", "dV5R", "dV6R", "dV7R", "dX", "dY", "dZ", "dCC5", "dCM5", "dLA", "dRA", "dLL", "dfl", "dfE", "dfC", "dfA", "dfM", "dfF", "dfH", "III", "aVR", "aVL", "aVF", "aVRneg", "V8", "V9", "V8R", "V9R", "D", "A", "J", "Defib", "Extern", "A1", "A2", "A3", "A4", "dV8", "dV9", "dV8R", "dV9R", "dD", "dA", "dj", "Chest", "V", "VR", "VL", "VF", "MCL", "MCL1", "MCL2", "MCL3", "MCL4", "MCL5", "MCL6", "CC", "CC1", "CC2", "CC3", "CC4", "CC6", "CC7", "CM", "CM1", "CM2", "CM3", "CM4", "CM6", "dIII", "daVR", "daVL", "daVF", "daVRneg", "dChest", "dV", "dVR", "dVL", "dVF", "CM7", "CH5", "CS5", "CB5", "CR5", "ML", "AB1", "AB2", "AB3", "AB4", "ES", "AS", "AI", "S", "dDefib", "dExtern", "da1", "da2", "da3", "da4", "dMCL1", "dMCL2", "dMCL3", "dMCL4", "dMCL5", "dMCL6", "RL", "CV5RL", "CV6LL", "CV6LU", "V10", "dMCL", "dCC", "dCC1", "dCC2", "dCC3", "dCC4", "dCC5", "dCC6", "dCM", "dCM1", "dCM2", "dCM3", "dCM4", "dCM6", "dCM7", "dCH5", "dCS5", "dCB5", "dCR5", "dML", "dAB1", "dAB2", "dAB3", "dAB4", "dES", "dAS", "dAI", "dS", "dRL", "dCV5RL", "dCV6LL", "dCV6LU", "dV10", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""}; if(idx > 184) { strcpy(label, "unknown"); } else { strcpy(label, scp_labels[idx]); } } int UI_SCPECG2EDFwindow::get_patient_data(FILE *inputfile) { char str[2048]; int i, j, n, len, tag; long long offset; void *pntr=NULL; if(inputfile == NULL) { return(-1); } offset = sp[1].file_offset + 16LL; for(int k=0; ; k++) { fseeko(inputfile, offset, SEEK_SET); if(fread(str, 3, 1, inputfile) != 1) { textEdit1->append("A read-error occurred (80)\n"); return(-1); } len = *((unsigned short *)(str + 1)); if((offset + len + 3 - sp[1].file_offset) > sp[1].section_length) { textEdit1->append("Found an error in section 1 (81)\n" "Conversion aborted\n"); return(-1); } offset += (len + 3); tag = *((unsigned char *)str); if(tag == 255) { return(0); } if(len) { n = len; if(n > 2046) { n = 2046; } if(fread(str, n, 1, inputfile) != 1) { textEdit1->append("A read-error occurred (82)\n"); return(-1); } str[n] = 0; if(tag == 2) // Patient ID { strncpy(pat_dat.pat_id, str, 20); pat_dat.pat_id[20] = 0; remove_trailing_spaces(pat_dat.pat_id); remove_leading_spaces(pat_dat.pat_id); } if(tag == 0) // Patient last name { strncpy(pat_dat.last_name, str, 20); pat_dat.last_name[20] = 0; remove_trailing_spaces(pat_dat.last_name); remove_leading_spaces(pat_dat.last_name); } if(tag == 1) // Patient first name { strncpy(pat_dat.first_name, str, 20); pat_dat.first_name[20] = 0; remove_trailing_spaces(pat_dat.first_name); remove_leading_spaces(pat_dat.first_name); } if(tag == 8) // Patient sex { pat_dat.sex = str[0]; } if(tag == 25) // startdate { pntr = str; pat_dat.startdate_year = *((unsigned short *)pntr); pat_dat.startdate_month = str[2]; pat_dat.startdate_day = str[3]; } if(tag == 26) // starttime { pat_dat.starttime_hour = str[0]; pat_dat.starttime_minute = str[1]; pat_dat.starttime_second = str[2]; } if(tag == 5) // birthdate { pntr = str; pat_dat.startdate_year = *((unsigned short *)pntr); pat_dat.startdate_month = str[2]; pat_dat.startdate_day = str[3]; } if(tag == 14) // machine ID acquiring device { pat_dat.lang_code = str[16]; strncpy(pat_dat.device_model, str + 8, 5); pat_dat.device_model[5] = 0; i = str[35]; i += 36; if(i < 1500) { strncpy(pat_dat.device_serial, str + i + 1, 48); pat_dat.device_serial[48] = 0; latin1_to_ascii(pat_dat.device_serial, 48); remove_trailing_spaces(pat_dat.device_serial); remove_leading_spaces(pat_dat.device_serial); } j = 0; for( ; i<1500; i++) { if(str[i] == 0) { j++; if(j == 1) { strncpy(pat_dat.device_ident, str + i + 1, 48); pat_dat.device_ident[48] = 0; latin1_to_ascii(pat_dat.device_ident, 48); remove_trailing_spaces(pat_dat.device_ident); remove_leading_spaces(pat_dat.device_ident); } if(j == 3) { strncpy(pat_dat.manufacturer, str + i + 1, 48); pat_dat.manufacturer[48] = 0; latin1_to_ascii(pat_dat.manufacturer, 48); remove_trailing_spaces(pat_dat.manufacturer); remove_leading_spaces(pat_dat.manufacturer); break; } } } } } } return(0); } edfbrowser_153_source/PaxHeaders.2978/ascii_export.h0000644000175000001440000000012712251654530021015 xustar000000000000000029 mtime=1386699096.46603258 29 atime=1386699096.46603258 29 ctime=1386699096.46603258 edfbrowser_153_source/ascii_export.h0000644000175000001440000000443612251654530020551 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef ASCIIEXPORTFORM1_H #define ASCIIEXPORTFORM1_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "mainwindow.h" #include "popup_messagewindow.h" #include "utils.h" class UI_Mainwindow; class UI_AsciiExportwindow : public QObject { Q_OBJECT public: UI_AsciiExportwindow(QWidget *parent); UI_Mainwindow *mainwindow; private: QDialog *AsciiExportDialog; QListWidget *filelist; QPushButton *CloseButton, *ExportButton; struct asciiedfparamblock{ int smp_per_record; int smp_written; int dig_min; int dig_max; double offset; int buf_offset; double phys_min; double phys_max; double time_step; double sense; } *edfparamascii; private slots: void ExportButtonClicked(); }; #endif // ASCIIEXPORTFORM1_H edfbrowser_153_source/PaxHeaders.2978/viewcurve.cpp0000644000175000001440000000013212251654530020672 xustar000000000000000030 mtime=1386699096.479032511 30 atime=1386699096.479032511 30 ctime=1386699096.479032511 edfbrowser_153_source/viewcurve.cpp0000644000175000001440000037717012251654530020442 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "viewcurve.h" ViewCurve::ViewCurve(QWidget *w_parent) : QWidget(w_parent) { int i; setAttribute(Qt::WA_OpaquePaintEvent); mainwindow = (UI_Mainwindow *)w_parent; special_pen = new QPen(Qt::SolidPattern, 0, Qt::DotLine, Qt::SquareCap, Qt::BevelJoin); annot_marker_pen = new QPen(Qt::SolidPattern, 0, Qt::DashLine, Qt::SquareCap, Qt::BevelJoin); signal_pen = new QPen(Qt::SolidPattern, 2, Qt::SolidLine, Qt::SquareCap, Qt::BevelJoin); ruler_pen = new QPen(Qt::SolidPattern, 0, Qt::SolidLine, Qt::SquareCap, Qt::BevelJoin); active_markers = (struct active_markersblock *)calloc(1, sizeof(struct active_markersblock)); annot_marker_moving = 0; use_move_events = 0; sidemenu_active = 0; draw_zoom_rectangle = 0; printing = 0; pressed_on_label = 0; original_sensitivity = (double *)calloc(1, sizeof(double[MAXSIGNALS])); backgroundcolor = Qt::gray; small_ruler_color = Qt::black; big_ruler_color = Qt::darkGray; mouse_rect_color = Qt::black; text_color = Qt::black; signal_color = Qt::blue; baseline_color = Qt::darkGray; crosshair_1.color = Qt::red; crosshair_2.color = Qt::cyan; floating_ruler_color = Qt::red; annot_marker_color = Qt::white; crosshair_1.active = 0; crosshair_2.active = 0; ruler_active = 0; crosshair_1.moving = 0; crosshair_2.moving = 0; ruler_moving = 0; crosshair_1.value = 0.0; crosshair_2.value = 0.0; printsize_x_factor=1.0, printsize_y_factor=1.0; printfont = new QFont; printfont->setFamily("Arial"); screensamples = (int *)calloc(1, sizeof(int[MAXSIGNALS])); cpu_cnt = QThread::idealThreadCount(); if(cpu_cnt < 1) cpu_cnt = 1; if(cpu_cnt > MAXSIGNALS) cpu_cnt = MAXSIGNALS; for(i=0; imousewheelsens < 1) return; if(mainwindow->files_open == 0) return; if(QApplication::keyboardModifiers() == Qt::ControlModifier) { if(wheel_event->delta() > 0) { if((mainwindow->viewtime_sync==VIEWTIME_SYNCED_OFFSET)||(mainwindow->viewtime_sync==VIEWTIME_SYNCED_ABSOLUT)||(mainwindow->viewtime_sync==VIEWTIME_USER_DEF_SYNCED)) { for(i=0; ifiles_open; i++) { if(mainwindow->timescale_doubler == 50) { mainwindow->edfheaderlist[i]->viewtime += (mainwindow->pagetime * 0.3); } else { mainwindow->edfheaderlist[i]->viewtime += (mainwindow->pagetime / 4); } l_tmp = mainwindow->edfheaderlist[i]->viewtime % TIME_DIMENSION; if(l_tmp < trshld) { mainwindow->edfheaderlist[i]->viewtime -= l_tmp; } if(l_tmp > (TIME_DIMENSION - trshld)) { mainwindow->edfheaderlist[i]->viewtime += (TIME_DIMENSION - l_tmp); } } } if(mainwindow->viewtime_sync==VIEWTIME_UNSYNCED) { if(mainwindow->timescale_doubler == 50) { mainwindow->edfheaderlist[mainwindow->sel_viewtime]->viewtime += (mainwindow->pagetime * 0.3); } else { mainwindow->edfheaderlist[mainwindow->sel_viewtime]->viewtime += (mainwindow->pagetime / 4); } l_tmp = mainwindow->edfheaderlist[mainwindow->sel_viewtime]->viewtime % TIME_DIMENSION; if(l_tmp < trshld) { mainwindow->edfheaderlist[mainwindow->sel_viewtime]->viewtime -= l_tmp; } if(l_tmp > (TIME_DIMENSION - trshld)) { mainwindow->edfheaderlist[mainwindow->sel_viewtime]->viewtime += (TIME_DIMENSION - l_tmp); } } if(mainwindow->timescale_doubler == 10) { mainwindow->timescale_doubler = 50; mainwindow->pagetime /= 2; } else { if(mainwindow->timescale_doubler == 50) { mainwindow->timescale_doubler = 20; mainwindow->pagetime /= 2.5; } else { mainwindow->timescale_doubler = 10; mainwindow->pagetime /= 2; } } } else { if((mainwindow->viewtime_sync==VIEWTIME_SYNCED_OFFSET)||(mainwindow->viewtime_sync==VIEWTIME_SYNCED_ABSOLUT)||(mainwindow->viewtime_sync==VIEWTIME_USER_DEF_SYNCED)) { for(i=0; ifiles_open; i++) { if(mainwindow->timescale_doubler == 20) { mainwindow->edfheaderlist[i]->viewtime -= (mainwindow->pagetime * 0.75); } else { mainwindow->edfheaderlist[i]->viewtime -= (mainwindow->pagetime / 2); } l_tmp = mainwindow->edfheaderlist[i]->viewtime % TIME_DIMENSION; if(l_tmp < trshld) { mainwindow->edfheaderlist[i]->viewtime -= l_tmp; } if(l_tmp > (TIME_DIMENSION - trshld)) { mainwindow->edfheaderlist[i]->viewtime += (TIME_DIMENSION - l_tmp); } } } if(mainwindow->viewtime_sync==VIEWTIME_UNSYNCED) { if(mainwindow->timescale_doubler == 20) { mainwindow->edfheaderlist[mainwindow->sel_viewtime]->viewtime -= (mainwindow->pagetime * 0.75); } else { mainwindow->edfheaderlist[mainwindow->sel_viewtime]->viewtime -= (mainwindow->pagetime / 2); } l_tmp = mainwindow->edfheaderlist[mainwindow->sel_viewtime]->viewtime % TIME_DIMENSION; if(l_tmp < trshld) { mainwindow->edfheaderlist[mainwindow->sel_viewtime]->viewtime -= l_tmp; } if(l_tmp > (TIME_DIMENSION - trshld)) { mainwindow->edfheaderlist[mainwindow->sel_viewtime]->viewtime += (TIME_DIMENSION - l_tmp); } } if(mainwindow->timescale_doubler == 10) { mainwindow->timescale_doubler = 20; mainwindow->pagetime *= 2; } else { if(mainwindow->timescale_doubler == 20) { mainwindow->timescale_doubler = 50; mainwindow->pagetime *= 2.5; } else { mainwindow->timescale_doubler = 10; mainwindow->pagetime *= 2; } } } } else { if((mainwindow->viewtime_sync==VIEWTIME_SYNCED_OFFSET)||(mainwindow->viewtime_sync==VIEWTIME_SYNCED_ABSOLUT)||(mainwindow->viewtime_sync==VIEWTIME_USER_DEF_SYNCED)) { for(i=0; ifiles_open; i++) { if(wheel_event->delta() > 0) { mainwindow->edfheaderlist[i]->viewtime -= (mainwindow->pagetime / mainwindow->mousewheelsens); } else { mainwindow->edfheaderlist[i]->viewtime += (mainwindow->pagetime / mainwindow->mousewheelsens); } } } if(mainwindow->viewtime_sync==VIEWTIME_UNSYNCED) { if(wheel_event->delta() > 0) { mainwindow->edfheaderlist[mainwindow->sel_viewtime]->viewtime -= (mainwindow->pagetime / mainwindow->mousewheelsens); } else { mainwindow->edfheaderlist[mainwindow->sel_viewtime]->viewtime += (mainwindow->pagetime / mainwindow->mousewheelsens); } } } mainwindow->setup_viewbuf(); } void ViewCurve::mousePressEvent(QMouseEvent *press_event) { int i, j, baseline, signalcomps, m_x, m_y, h_size; struct signalcompblock **signalcomp; if(!mainwindow->files_open) return; if(!mainwindow->signalcomps) return; signalcomps = mainwindow->signalcomps; signalcomp = mainwindow->signalcomp; m_x = press_event->x(); m_y = press_event->y(); mouse_press_coordinate_x = m_x; mouse_press_coordinate_y = m_y; pressed_on_label = 0; h_size = (int)(4.0 / mainwindow->pixelsizefactor); setFocus(Qt::MouseFocusReason); if(press_event->button()==Qt::LeftButton) { crosshair_1.moving = 0; crosshair_2.moving = 0; ruler_moving = 0; use_move_events = 1; setMouseTracking(TRUE); mouse_old_x = m_x; mouse_old_y = m_y; if(ruler_active) { if((m_y>(ruler_y_position + h_size + 10))&&(m_y<(ruler_y_position + h_size + 30))&&(m_x>ruler_x_position)&&(m_x<(ruler_x_position + 60))) { if(floating_ruler_value) { floating_ruler_value = 0; } else { floating_ruler_value = 1; } update(); return; } else if((m_y>ruler_y_position)&&(m_y<(ruler_y_position + ((int)(4.0 / mainwindow->pixelsizefactor))))&&(m_x>ruler_x_position)&&(m_x<(ruler_x_position + 150 + (w / 5)))) { ruler_moving = 1; } } if(!ruler_moving) { if(crosshair_1.active) { if((m_y(crosshair_1.y_position - 51))&&(m_x>crosshair_1.x_position)&&(m_x<(crosshair_1.x_position + 171))) { crosshair_1.moving = 1; } if(m_x>(crosshair_1.x_position-10)&&(m_x<(crosshair_1.x_position + 10))) { crosshair_1.moving = 1; } } } if((!ruler_moving)&&(!crosshair_1.moving)) { if(crosshair_2.active) { if((m_y(crosshair_2.y_position - 80))&&(m_x>crosshair_2.x_position)&&(m_x<(crosshair_2.x_position + 171))) { crosshair_2.moving = 1; } if(m_x>(crosshair_2.x_position-10)&&(m_x<(crosshair_2.x_position + 10))) { crosshair_2.moving = 1; } } } if(mainwindow->annot_editor_active) { if((!ruler_moving)&&(!crosshair_1.moving)&&(!crosshair_2.moving)) { for(i=0; icount; i++) { if(m_x>(active_markers->list[i]->x_pos-5)&&(m_x<(active_markers->list[i]->x_pos+5))) { active_markers->selected = i; annot_marker_moving = 1; active_markers->list[i]->selected = 1; break; } } } } if((!ruler_moving)&&(!crosshair_1.moving)&&(!crosshair_2.moving)&&(!annot_marker_moving)) { for(i=0; i(baseline-24))&&(m_x>3)&&(m_x<110)) { original_screen_offset = signalcomp[i]->screen_offset; signalcomp[i]->hasoffsettracking = 1; signal_nr = i; pressed_on_label = i + 1; label_press_y_position = m_y; break; } } } if((!pressed_on_label)&&(!ruler_moving)&&(!crosshair_1.moving)&&(!crosshair_2.moving)&&(!annot_marker_moving)) { draw_zoom_rectangle = 1; mouse_x = m_x; mouse_y = m_y; } } if(press_event->button()==Qt::RightButton) { for(i=0; ihascursor1 = 0; signalcomp[i]->hascursor2 = 0; signalcomp[i]->hasoffsettracking = 0; } crosshair_1.active = 0; crosshair_2.active = 0; crosshair_1.moving = 0; crosshair_2.moving = 0; use_move_events = 0; setMouseTracking(FALSE); for(i=0; i(baseline-24))&&(m_x>3)&&(m_x<110)) { for(j=0; jnum_of_signals; j++) { original_sensitivity[j] = signalcomp[i]->sensitivity[j]; } original_screen_offset = signalcomp[i]->screen_offset; signalcomp[i]->hasgaintracking = 1; use_move_events = 1; setMouseTracking(TRUE); signal_nr = i; break; } } if(!use_move_events) { for(i=0; ihasruler = 0; } ruler_active = 0; ruler_moving = 0; update(); } } } void ViewCurve::mouseReleaseEvent(QMouseEvent *release_event) { int i, j, baseline, signalcomps, m_x, m_y; double zoomfactor; struct signalcompblock **signalcomp; if(!mainwindow->files_open) return; if(!mainwindow->signalcomps) return; signalcomps = mainwindow->signalcomps; signalcomp = mainwindow->signalcomp; m_x = release_event->x(); m_y = release_event->y(); if(release_event->button()==Qt::LeftButton) { if(crosshair_1.moving) { mainwindow->annotationEditDock->annotEditSetOnset(crosshair_1.time_relative); } if(crosshair_2.moving) { mainwindow->annotationEditDock->annotEditSetDuration(crosshair_2.time_relative - crosshair_1.time_relative); } if(annot_marker_moving) { active_markers->list[active_markers->selected]->x_pos = m_x; active_markers->list[active_markers->selected]->onset = ((long long)((((double)m_x) / w) * mainwindow->pagetime)) + mainwindow->edfheaderlist[active_markers->file_num]->viewtime + mainwindow->edfheaderlist[active_markers->file_num]->starttime_offset; active_markers->list[active_markers->selected]->modified = 1; active_markers->list[active_markers->selected]->selected = 1; mainwindow->annotationEditDock->set_selected_annotation(active_markers->list[active_markers->selected]); mainwindow->annotations_dock[active_markers->file_num]->updateList(); mainwindow->annotations_edited = 1; update(); } ruler_moving = 0; crosshair_1.moving = 0; crosshair_2.moving = 0; annot_marker_moving = 0; use_move_events = 0; setMouseTracking(FALSE); if(draw_zoom_rectangle) { draw_zoom_rectangle = 0; if((m_x>(mouse_press_coordinate_x + 50))&&(m_y > mouse_press_coordinate_y + 50)) { for(i=0; ifiles_open; i++) { mainwindow->zoomhistory->viewtime[mainwindow->zoomhistory->pntr][i] = mainwindow->edfheaderlist[i]->viewtime; } mainwindow->zoomhistory->pagetime[mainwindow->zoomhistory->pntr] = mainwindow->pagetime; for(i=0; izoomhistory->voltpercm[mainwindow->zoomhistory->pntr][i] = signalcomp[i]->voltpercm; mainwindow->zoomhistory->screen_offset[mainwindow->zoomhistory->pntr][i] = signalcomp[i]->screen_offset; for(j=0; jnum_of_signals; j++) { mainwindow->zoomhistory->sensitivity[mainwindow->zoomhistory->pntr][i][j] = signalcomp[i]->sensitivity[j]; } } mainwindow->zoomhistory->pntr++; mainwindow->zoomhistory->pntr %= 64; for(i=0; ifiles_open; i++) { mainwindow->edfheaderlist[i]->viewtime += (long long)(((double)mainwindow->pagetime / (double)w) * (double)mouse_press_coordinate_x); } mainwindow->pagetime = (long long)((double)mainwindow->pagetime / ((double)w / (double)(m_x - mouse_press_coordinate_x))); if(mainwindow->pagetime<1) mainwindow->pagetime = 1; zoomfactor = (double)h / (double)(m_y - mouse_press_coordinate_y); for(i=0; isignalcomp[i]->screen_offset = mainwindow->signalcomp[i]->screen_offset * zoomfactor; mainwindow->signalcomp[i]->screen_offset += (((double)h * (zoomfactor - 1.0) * (double)(i + 1.0)) / (double)(signalcomps + 1.0)); mainwindow->signalcomp[i]->screen_offset -= ((double)mouse_press_coordinate_y * zoomfactor); mainwindow->signalcomp[i]->voltpercm = mainwindow->signalcomp[i]->voltpercm / ((double)h / (double)(m_y - mouse_press_coordinate_y)); for(j=0; jsignalcomp[i]->num_of_signals; j++) { mainwindow->signalcomp[i]->sensitivity[j] = mainwindow->signalcomp[i]->sensitivity[j] * ((double)h / (double)(m_y - mouse_press_coordinate_y)); } } mainwindow->zoomhistory->history_size_tail++; mainwindow->zoomhistory->history_size_front = 0; mainwindow->setup_viewbuf(); } else { update(); } } for(i=0; ihasoffsettracking) { signalcomp[i]->hasoffsettracking = 0; use_move_events = 0; setMouseTracking(FALSE); update(); } } for(i=0; i(baseline-24))&&(m_x>3)&&(m_x<110)) { if(pressed_on_label == (i + 1)) { use_move_events = 0; setMouseTracking(FALSE); update(); signal_nr = i; exec_sidemenu(i); break; } } } } if(release_event->button()==Qt::RightButton) { for(i=0; ihasgaintracking) { signalcomp[i]->hasgaintracking = 0; use_move_events = 0; setMouseTracking(FALSE); update(); } } } pressed_on_label = 0; } void ViewCurve::mouseMoveEvent(QMouseEvent *move_event) { int i, j, signalcomps, delta_y; double d_temp; struct signalcompblock **signalcomp; if(!mainwindow->files_open) return; if(!mainwindow->signalcomps) return; if(use_move_events) { signalcomps = mainwindow->signalcomps; signalcomp = mainwindow->signalcomp; mouse_x = move_event->x(); mouse_y = move_event->y(); if(pressed_on_label) { if((mouse_y > (label_press_y_position + 10)) || (mouse_y < (label_press_y_position - 10))) { pressed_on_label = 0; } } if(crosshair_1.moving) { if(mouse_x<(w-100)) { crosshair_1.x_position += (mouse_x - mouse_old_x); mouse_old_x = mouse_x; if(crosshair_1.x_position<0) { crosshair_1.x_position = 0; } } if((mouse_y<(h-30))&&(mouse_y>30)) { crosshair_1.y_position += (mouse_y - mouse_old_y); mouse_old_y = mouse_y; if(crosshair_1.y_position<1) { crosshair_1.y_position = 1; } } } if(crosshair_2.moving) { if(mouse_x<(w-100)) { crosshair_2.x_position += (mouse_x - mouse_old_x); mouse_old_x = mouse_x; if(crosshair_2.x_position<0) { crosshair_2.x_position = 0; } } if((mouse_y<(h-30))&&(mouse_y>30)) { crosshair_2.y_position += (mouse_y - mouse_old_y); mouse_old_y = mouse_y; if(crosshair_2.y_position<1) { crosshair_2.y_position = 1; } } } if(ruler_moving) { if(mouse_x<(w-100)) { ruler_x_position += (mouse_x - mouse_old_x); mouse_old_x = mouse_x; if(ruler_x_position<1) { ruler_x_position = 1; } } if(mouse_y<(h-100)) { ruler_y_position += (mouse_y - mouse_old_y); mouse_old_y = mouse_y; if(ruler_y_position<1) { ruler_y_position = 1; } } } if(annot_marker_moving) { active_markers->list[active_markers->selected]->x_pos = mouse_x; active_markers->list[active_markers->selected]->onset = ((long long)((((double)mouse_x) / w) * mainwindow->pagetime)) + mainwindow->edfheaderlist[active_markers->file_num]->viewtime + mainwindow->edfheaderlist[active_markers->file_num]->starttime_offset; } delta_y = mouse_y - mouse_press_coordinate_y; for(i=0; ihasoffsettracking) { signalcomp[i]->screen_offset = original_screen_offset + delta_y; } if(signalcomp[i]->hasgaintracking) { for(j=0; jnum_of_signals; j++) { d_temp = original_sensitivity[j] * (1.0 + ((double)(-delta_y) / 50.0)); if(d_temp>0.000001) { signalcomp[i]->sensitivity[j] = d_temp; d_temp = signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[j]].bitvalue / (signalcomp[i]->sensitivity[j] * mainwindow->pixelsizefactor); signalcomp[i]->voltpercm = d_temp; } } signalcomp[i]->screen_offset = original_screen_offset * (signalcomp[i]->sensitivity[0] / original_sensitivity[0]); } } if(draw_zoom_rectangle||annot_marker_moving) { update(); } else { drawCurve_stage_1(); } } } void ViewCurve::paintEvent(QPaintEvent *) { QPainter paint(this); drawCurve_stage_2(&paint); } void ViewCurve::print_to_printer() { int i, j, len; char path[MAX_PATH_LENGTH]; double height_factor; struct date_time_struct date_time; if(!mainwindow->files_open) return; if(!mainwindow->signalcomps) return; QPrinter print(QPrinter::HighResolution); print.setOutputFormat(QPrinter::NativeFormat); print.setPageSize(QPrinter::A4); print.setOrientation(QPrinter::Landscape); print.setCreator(PROGRAM_NAME); QPrintDialog printerdialog(&print, this); printerdialog.setWindowTitle("Print"); if(printerdialog.exec()==QDialog::Accepted) { if(blackwhite_printing) { backup_colors_for_printing(); } height_factor = ((double)print.pageRect().height()) / 9000.0; QPainter paint(&print); paint.translate(0, (int)(260.0 * height_factor)); drawCurve_stage_1(&paint, print.pageRect().width() - 30, (int)((double)print.pageRect().height() - (260.0 * height_factor) - 30), 2); paint.translate(0, -(int)(260.0 * height_factor)); len = strlen(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename); for(i=len-1; i>=0; i--) { if((mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename[i] == '/')||(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename[i] == '\\')) break; } i++; strcpy(path, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename + i); strcat(path, " "); strcat(path, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->patient); remove_trailing_spaces(path); utc_to_date_time(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->utc_starttime, &date_time); date_time.month_str[0] += 32; date_time.month_str[1] += 32; date_time.month_str[2] += 32; sprintf(path + strlen(path), " %i %s %i ", date_time.day, date_time.month_str, date_time.year); if(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->edfplus||mainwindow->edfheaderlist[mainwindow->sel_viewtime]->bdfplus) { strcat(path, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->recording + 22); } else { strcat(path, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->recording); } remove_trailing_spaces(path); len = strlen(path); for(j=0; jsetPixelSize((int)((double)print.pageRect().width() / 104.0)); paint.setPen(text_color); paint.setFont(*printfont); paint.drawText(0, (int)(160.0 * height_factor), path); if(blackwhite_printing) { restore_colors_after_printing(); } drawCurve_stage_1(); } } void ViewCurve::print_to_postscript() { double height_factor; int i, j, len; char path[MAX_PATH_LENGTH]; struct date_time_struct date_time; if(!mainwindow->files_open) return; if(!mainwindow->signalcomps) return; 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[mainwindow->sel_viewtime]->filename, MAX_PATH_LENGTH - len); remove_extension_from_filename(path); strcat(path, ".ps"); strcpy(path, QFileDialog::getSaveFileName(0, "Print to PostScript", QString::fromLocal8Bit(path), "PostScript files (*.ps *.PS)").toLocal8Bit().data()); if(!strcmp(path, "")) { return; } get_directory_from_path(mainwindow->recent_savedir, path, MAX_PATH_LENGTH); QPrinter print(QPrinter::HighResolution); print.setOutputFormat(QPrinter::PostScriptFormat); print.setOutputFileName(QString::fromLocal8Bit(path)); print.setPageSize(QPrinter::A4); print.setOrientation(QPrinter::Landscape); print.setCreator(PROGRAM_NAME); if(blackwhite_printing) { backup_colors_for_printing(); } height_factor = ((double)print.pageRect().height()) / 9000.0; QPainter paint(&print); paint.translate(0, (int)(260.0 * height_factor)); drawCurve_stage_1(&paint, print.pageRect().width() - 30, (int)((double)print.pageRect().height() - (260.0 * height_factor) - 30), 2); paint.translate(0, -(int)(260.0 * height_factor)); len = strlen(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename); for(i=len; i>=0; i--) { if((mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename[i] == '/')||(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename[i] == '\\')) { break; } } i++; strcpy(path, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename + i); strcat(path, " "); strcat(path, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->patient); remove_trailing_spaces(path); utc_to_date_time(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->utc_starttime, &date_time); date_time.month_str[0] += 32; date_time.month_str[1] += 32; date_time.month_str[2] += 32; sprintf(path + strlen(path), " %i %s %i ", date_time.day, date_time.month_str, date_time.year); if(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->edfplus||mainwindow->edfheaderlist[mainwindow->sel_viewtime]->bdfplus) { strcat(path, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->recording + 22); } else { strcat(path, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->recording); } remove_trailing_spaces(path); len = strlen(path); for(j=0; jsetPixelSize((int)((double)print.pageRect().width() / 104.0)); paint.setPen(text_color); paint.setFont(*printfont); paint.drawText(0, (int)(160.0 * height_factor), path); if(blackwhite_printing) { restore_colors_after_printing(); } drawCurve_stage_1(); } void ViewCurve::print_to_pdf() { double height_factor; int i, j, len; char path[MAX_PATH_LENGTH]; struct date_time_struct date_time; if(!mainwindow->files_open) return; if(!mainwindow->signalcomps) return; 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[mainwindow->sel_viewtime]->filename, MAX_PATH_LENGTH - len); remove_extension_from_filename(path); strcat(path, ".pdf"); strcpy(path, QFileDialog::getSaveFileName(0, "Print to PDF", QString::fromLocal8Bit(path), "PDF files (*.pdf *.PDF)").toLocal8Bit().data()); if(!strcmp(path, "")) { return; } get_directory_from_path(mainwindow->recent_savedir, path, MAX_PATH_LENGTH); QPrinter print(QPrinter::HighResolution); print.setOutputFormat(QPrinter::PdfFormat); print.setOutputFileName(QString::fromLocal8Bit(path)); print.setPageSize(QPrinter::A4); print.setOrientation(QPrinter::Landscape); print.setCreator(PROGRAM_NAME); if(blackwhite_printing) { backup_colors_for_printing(); } height_factor = ((double)print.pageRect().height()) / 9000.0; QPainter paint(&print); paint.translate(0, (int)(260.0 * height_factor)); drawCurve_stage_1(&paint, print.pageRect().width() - 30, (int)((double)print.pageRect().height() - (260.0 * height_factor) - 30), 2); paint.translate(0, -(int)(260.0 * height_factor)); len = strlen(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename); for(i=len; i>=0; i--) { if((mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename[i] == '/')||(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename[i] == '\\')) { break; } } i++; strcpy(path, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename + i); strcat(path, " "); strcat(path, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->patient); remove_trailing_spaces(path); utc_to_date_time(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->utc_starttime, &date_time); date_time.month_str[0] += 32; date_time.month_str[1] += 32; date_time.month_str[2] += 32; sprintf(path + strlen(path), " %i %s %i ", date_time.day, date_time.month_str, date_time.year); if(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->edfplus||mainwindow->edfheaderlist[mainwindow->sel_viewtime]->bdfplus) { strcat(path, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->recording + 22); } else { strcat(path, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->recording); } remove_trailing_spaces(path); len = strlen(path); for(j=0; jsetPixelSize((int)((double)print.pageRect().width() / 104.0)); paint.setPen(text_color); paint.setFont(*printfont); paint.drawText(0, (int)(160.0 * height_factor), path); if(blackwhite_printing) { restore_colors_after_printing(); } drawCurve_stage_1(); } void ViewCurve::print_to_image(int w_img, int h_img) { int i, j, len; char path[MAX_PATH_LENGTH], str[1024]; struct date_time_struct date_time; if(!mainwindow->files_open) return; if(!mainwindow->signalcomps) return; 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[mainwindow->sel_viewtime]->filename, MAX_PATH_LENGTH - len); remove_extension_from_filename(path); strcat(path, ".png"); strcpy(path, QFileDialog::getSaveFileName(0, "Print to Image", QString::fromLocal8Bit(path), "PNG (*.png *.PNG)").toLocal8Bit().data()); if(!strcmp(path, "")) { return; } get_directory_from_path(mainwindow->recent_savedir, path, MAX_PATH_LENGTH); QPixmap pixmap(w_img, h_img); QPainter paint(&pixmap); paint.fillRect(0, 0, w_img, h_img, backgroundcolor); paint.translate(0, 25); drawCurve_stage_1(&paint, w_img, h_img - 25, 0); paint.translate(0, -25); len = strlen(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename); for(i=len; i>=0; i--) { if((mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename[i] == '/')||(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename[i] == '\\')) { break; } } i++; strcpy(str, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->filename + i); strcat(str, " "); strcat(str, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->patient); remove_trailing_spaces(str); utc_to_date_time(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->utc_starttime, &date_time); date_time.month_str[0] += 32; date_time.month_str[1] += 32; date_time.month_str[2] += 32; sprintf(str + strlen(str), " %i %s %i ", date_time.day, date_time.month_str, date_time.year); if(mainwindow->edfheaderlist[mainwindow->sel_viewtime]->edfplus||mainwindow->edfheaderlist[mainwindow->sel_viewtime]->bdfplus) { strcat(str, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->recording + 22); } else { strcat(str, mainwindow->edfheaderlist[mainwindow->sel_viewtime]->recording); } len = strlen(str); for(j=0; jsetPixelSize((int)((double)w / 104.0)); paint.setPen(text_color); paint.setFont(*printfont); paint.drawText(5, 15, str); pixmap.save(QString::fromLocal8Bit(path), "PNG", 90); drawCurve_stage_1(); } void ViewCurve::drawCurve_stage_2(QPainter *painter, int w_width, int w_height, int print_linewidth) { int i, j, x_pix=0, signalcomps, baseline, m_pagetime, vert_ruler_offset, vertical_distance, marker_x; char *viewbuf, string[256], str2[32]; long long time_ppixel, ll_elapsed_time, l_time, l_tmp; struct signalcompblock **signalcomp; struct annotationblock *annot; QFont paintersfont; if(mainwindow->exit_in_progress) { return; } signalcomps = mainwindow->signalcomps; signalcomp = mainwindow->signalcomp; viewbuf = mainwindow->viewbuf; vertical_distance = 1; painter_pixelsizefactor = 1.0 / mainwindow->pixelsizefactor; if(!w_width||!w_height) { w = width(); h = height(); paintersfont = *mainwindow->myfont; paintersfont.setBold(TRUE); paintersfont.setWeight(QFont::Black); painter->setFont(paintersfont); printing = 0; } else { w = w_width; h = w_height; #ifdef Q_WS_X11 printfont->setPixelSize((int)((double)w / 104.0)); #endif #ifdef Q_WS_MAC printfont->setPixelSize((int)((double)w / 104.0)); #endif #ifdef Q_WS_WIN printfont->setPixelSize((int)((double)w / 104.0)); #endif painter->setFont(*printfont); printsize_x_factor = ((double)w_width) / ((double)width()); printsize_y_factor = ((double)w_height) / ((double)height()); painter_pixelsizefactor *= printsize_y_factor; printing = 1; } for(i=0; isample_pixel_ratio = (double)signalcomp[i]->samples_on_screen / (double)w; } painter->fillRect(0, 0, w, h, backgroundcolor); m_pagetime = (int)(mainwindow->pagetime / TIME_DIMENSION); time_ppixel = mainwindow->pagetime / w; if(mainwindow->files_open&&mainwindow->signalcomps) { ll_elapsed_time = mainwindow->edfheaderlist[mainwindow->sel_viewtime]->viewtime; } else { ll_elapsed_time = 0; } ruler_pen->setWidth(print_linewidth); if(printing) { ruler_pen->setColor(Qt::black); painter->setPen(*ruler_pen); painter->drawLine(0, 0, 0, h-1); painter->drawLine(0, 0, w-1, 0); painter->drawLine(w-1, h-1, w-1, 0); painter->drawLine(w-1, h-1, 0, h-1); } if(m_pagetime<=20) { ruler_pen->setColor(small_ruler_color); painter->setPen(*ruler_pen); for(x_pix=0; x_pixdrawLine(x_pix, 0, x_pix, 4 * printsize_y_factor); } else { painter->drawLine(x_pix, 0, x_pix, 4); } } if(((ll_elapsed_time / TIME_DIMENSION)!=((ll_elapsed_time + time_ppixel) / TIME_DIMENSION)) || ((ll_elapsed_time < time_ppixel) && (ll_elapsed_time > -time_ppixel))) { if(x_pix) { ruler_pen->setColor(big_ruler_color); painter->setPen(*ruler_pen); painter->drawLine(x_pix, 0, x_pix, h); ruler_pen->setColor(small_ruler_color); painter->setPen(*ruler_pen); } if(printing) { painter->drawLine(x_pix, 0, x_pix, 7 * printsize_y_factor); } else { painter->drawLine(x_pix, 0, x_pix, 7); } } ll_elapsed_time += time_ppixel; } } if((m_pagetime>20)&&(m_pagetime<100)) { ruler_pen->setColor(small_ruler_color); painter->setPen(*ruler_pen); for(x_pix=0; x_pixdrawLine(x_pix, 0, x_pix, 4 * printsize_y_factor); } else { painter->drawLine(x_pix, 0, x_pix, 4); } } if(((ll_elapsed_time / TIME_DIMENSION)!=((ll_elapsed_time + time_ppixel) / TIME_DIMENSION)) || ((ll_elapsed_time < time_ppixel) && (ll_elapsed_time > -time_ppixel))) { if(x_pix) { ruler_pen->setColor(big_ruler_color); painter->setPen(*ruler_pen); painter->drawLine(x_pix, 0, x_pix, h); ruler_pen->setColor(small_ruler_color); painter->setPen(*ruler_pen); } if(printing) { painter->drawLine(x_pix, 0, x_pix, 7 * printsize_y_factor); } else { painter->drawLine(x_pix, 0, x_pix, 7); } } ll_elapsed_time += time_ppixel; } } if((m_pagetime>=100)&&(m_pagetime<1000)) { ruler_pen->setColor(small_ruler_color); painter->setPen(*ruler_pen); for(x_pix=0; x_pixdrawLine(x_pix, 0, x_pix, 4 * printsize_y_factor); } else { painter->drawLine(x_pix, 0, x_pix, 4); } } if(((ll_elapsed_time / (TIME_DIMENSION * 10))!=((ll_elapsed_time + time_ppixel) / (TIME_DIMENSION * 10))) || ((ll_elapsed_time < time_ppixel) && (ll_elapsed_time > -time_ppixel))) { if(x_pix) { ruler_pen->setColor(big_ruler_color); painter->setPen(*ruler_pen); painter->drawLine(x_pix, 0, x_pix, h); ruler_pen->setColor(small_ruler_color); painter->setPen(*ruler_pen); } if(printing) { painter->drawLine(x_pix, 0, x_pix, 7 * printsize_y_factor); } else { painter->drawLine(x_pix, 0, x_pix, 7); } } ll_elapsed_time += time_ppixel; } } if((m_pagetime>=1000)&&(m_pagetime<5000)) { ruler_pen->setColor(small_ruler_color); painter->setPen(*ruler_pen); for(x_pix=0; x_pixdrawLine(x_pix, 0, x_pix, 4 * printsize_y_factor); } else { painter->drawLine(x_pix, 0, x_pix, 4); } } if(((ll_elapsed_time / (TIME_DIMENSION * 60))!=((ll_elapsed_time + time_ppixel) / (TIME_DIMENSION * 60))) || ((ll_elapsed_time < time_ppixel) && (ll_elapsed_time > -time_ppixel))) { if(x_pix) { ruler_pen->setColor(big_ruler_color); painter->setPen(*ruler_pen); painter->drawLine(x_pix, 0, x_pix, h); ruler_pen->setColor(small_ruler_color); painter->setPen(*ruler_pen); } if(printing) { painter->drawLine(x_pix, 0, x_pix, 7 * printsize_y_factor); } else { painter->drawLine(x_pix, 0, x_pix, 7); } } ll_elapsed_time += time_ppixel; } } if((m_pagetime>=5000)&&(m_pagetime<173000)) { ruler_pen->setColor(small_ruler_color); painter->setPen(*ruler_pen); for(x_pix=0; x_pixdrawLine(x_pix, 0, x_pix, 4 * printsize_y_factor); } else { painter->drawLine(x_pix, 0, x_pix, 4); } } if(((ll_elapsed_time / (TIME_DIMENSION * 3600))!=((ll_elapsed_time + time_ppixel) / (TIME_DIMENSION * 3600))) || ((ll_elapsed_time < time_ppixel) && (ll_elapsed_time > -time_ppixel))) { if(x_pix) { ruler_pen->setColor(big_ruler_color); painter->setPen(*ruler_pen); painter->drawLine(x_pix, 0, x_pix, h); ruler_pen->setColor(small_ruler_color); painter->setPen(*ruler_pen); } if(printing) { painter->drawLine(x_pix, 0, x_pix, 7 * printsize_y_factor); } else { painter->drawLine(x_pix, 0, x_pix, 7); } } ll_elapsed_time += time_ppixel; } } if((m_pagetime>=173000)&&(m_pagetime<3000000)) { ruler_pen->setColor(small_ruler_color); painter->setPen(*ruler_pen); for(x_pix=0; x_pixdrawLine(x_pix, 0, x_pix, 4 * printsize_y_factor); } else { painter->drawLine(x_pix, 0, x_pix, 4); } } if(((ll_elapsed_time / (TIME_DIMENSION * 86400))!=((ll_elapsed_time + time_ppixel) / (TIME_DIMENSION * 86400))) || ((ll_elapsed_time < time_ppixel) && (ll_elapsed_time > -time_ppixel))) { if(x_pix) { ruler_pen->setColor(big_ruler_color); painter->setPen(*ruler_pen); painter->drawLine(x_pix, 0, x_pix, h); ruler_pen->setColor(small_ruler_color); painter->setPen(*ruler_pen); } if(printing) { painter->drawLine(x_pix, 0, x_pix, 7 * printsize_y_factor); } else { painter->drawLine(x_pix, 0, x_pix, 7); } } ll_elapsed_time += time_ppixel; } } if((viewbuf==NULL)||(graphicBuf==NULL)||(screensamples==NULL)) { return; } if(mainwindow->show_baselines) { vertical_distance = h / (signalcomps + 1); painter->setPen(baseline_color); for(i=0; idrawLine(0, baseline, w, baseline); if(signalcomp[i]->voltpercm < 0.1) { strcpy(str2, "%+.3f "); } else if(signalcomp[i]->voltpercm < 1.0) { strcpy(str2, "%+.2f "); } else if(signalcomp[i]->voltpercm < 10.0) { strcpy(str2, "%+.1f "); } else { strcpy(str2, "%+.0f "); } strcat(str2, signalcomp[i]->physdimension); for(j=1; j<18; j++) { vert_ruler_offset = j * painter_pixelsizefactor; if(signalcomps!=1) { if(vert_ruler_offset>((vertical_distance / 2)) - 8) { break; } } if(printing) { if((baseline + vert_ruler_offset)>(h - (15 * printsize_y_factor))) { break; } if((baseline - vert_ruler_offset)<(15 * printsize_y_factor)) { break; } } else { if((baseline + vert_ruler_offset)>(h - 15)) { break; } if((baseline - vert_ruler_offset)<15) { break; } } painter->drawLine(0, baseline - vert_ruler_offset, w, baseline - vert_ruler_offset); if(printing) { snprintf(string, 128, str2, ((signalcomp[i]->voltpercm * j) + ((signalcomp[i]->screen_offset * signalcomp[i]->voltpercm) / (painter_pixelsizefactor / printsize_y_factor))) * (double)signalcomp[i]->polarity); } else { snprintf(string, 128, str2, ((signalcomp[i]->voltpercm * j) + ((signalcomp[i]->screen_offset * signalcomp[i]->voltpercm) / painter_pixelsizefactor)) * (double)signalcomp[i]->polarity); } painter->drawText(5 * printsize_x_factor, baseline - vert_ruler_offset - (4 * printsize_y_factor), string); painter->drawLine(0, baseline + vert_ruler_offset, w, baseline + vert_ruler_offset); if(printing) { snprintf(string, 128, str2, (((signalcomp[i]->screen_offset * signalcomp[i]->voltpercm) / (painter_pixelsizefactor / printsize_y_factor)) - (signalcomp[i]->voltpercm * j)) * (double)signalcomp[i]->polarity); } else { snprintf(string, 128, str2, (((signalcomp[i]->screen_offset * signalcomp[i]->voltpercm) / painter_pixelsizefactor) - (signalcomp[i]->voltpercm * j)) * (double)signalcomp[i]->polarity); } painter->drawText(5 * printsize_x_factor, baseline + vert_ruler_offset - (4 * printsize_y_factor), string); } } } if(mainwindow->show_annot_markers) { annot_marker_pen->setColor(annot_marker_color); annot_marker_pen->setWidth(print_linewidth); painter->setPen(*annot_marker_pen); if(!annot_marker_moving) { active_markers->count = 0; } for(i=0; ifiles_open; i++) { annot = mainwindow->annotationlist[i]; j = 0; while(annot!=NULL) { l_tmp = annot->onset - mainwindow->edfheaderlist[i]->starttime_offset; if((l_tmp > (mainwindow->edfheaderlist[i]->viewtime - TIME_DIMENSION)) && (!annot->hided) && (!annot->hided_in_list)) { if(l_tmp > (mainwindow->edfheaderlist[i]->viewtime + mainwindow->pagetime)) { break; } l_tmp -= mainwindow->edfheaderlist[i]->viewtime; marker_x = (int)((((double)w) / mainwindow->pagetime) * l_tmp); painter->drawLine(marker_x, 0, marker_x, h); l_tmp = annot->onset - mainwindow->edfheaderlist[i]->starttime_offset; if(l_tmp < 0LL) { snprintf(string, 32, "-%i:%02i:%02i.%04i", (int)(((-(l_tmp)) / TIME_DIMENSION)/ 3600LL), (int)((((-(l_tmp)) / TIME_DIMENSION) % 3600LL) / 60LL), (int)(((-(l_tmp)) / TIME_DIMENSION) % 60LL), (int)((((-(l_tmp)) % TIME_DIMENSION) / 1000LL))); } else { snprintf(string, 32, "%i:%02i:%02i.%04i", (int)((l_tmp / TIME_DIMENSION)/ 3600LL), (int)(((l_tmp / TIME_DIMENSION) % 3600LL) / 60LL), (int)((l_tmp / TIME_DIMENSION) % 60LL), (int)(((l_tmp % TIME_DIMENSION) / 1000LL))); } remove_trailing_zeros(string); if(printing) { painter->drawText(marker_x + (5 * printsize_x_factor), h - (25 * printsize_y_factor), string); } else { painter->drawText(marker_x + 5, h - 65 + ((j % 3) * 30), string); } strncpy(string, annot->annotation, 20); string[20] = 0; if(printing) { painter->drawText(marker_x + (5 * printsize_x_factor), h - (40 * printsize_y_factor), QString::fromUtf8(string)); } else { painter->drawText(marker_x + 5, h - 80 + ((j % 3) * 30), QString::fromUtf8(string)); } if(!annot_marker_moving) { if(active_markers->countx_pos = marker_x; active_markers->list[active_markers->count] = annot; active_markers->count++; } } } annot = annot->next_annotation; j++; } } } if(mainwindow->clip_to_pane) { painter->setClipping(TRUE); vertical_distance = h / (signalcomps + 1); } for(i=0; iclip_to_pane) { painter->setClipRect(0, vertical_distance * i + (vertical_distance / 2), w, vertical_distance); } if(printing) { signal_pen->setColor((Qt::GlobalColor)signalcomp[i]->color); signal_pen->setWidth(print_linewidth); painter->setPen(*signal_pen); } else { painter->setPen((Qt::GlobalColor)signalcomp[i]->color); } for(j=0; jdrawLine(graphicBuf[j].graphicLine[i].x1, graphicBuf[j].graphicLine[i].y1, graphicBuf[j].graphicLine[i].x2, graphicBuf[j].graphicLine[i].y2); } } painter->setClipping(FALSE); for(i=0; isetPen((Qt::GlobalColor)signalcomp[i]->color); if(signalcomp[i]->hascursor1) { if(printing) { painter->setPen((Qt::GlobalColor)crosshair_1.color); painter->drawLine(0, crosshair_1.y_value, w, crosshair_1.y_value); painter->drawLine((int)((double)crosshair_1.x_position * printsize_x_factor), 0, (int)((double)crosshair_1.x_position * printsize_x_factor), h); snprintf(string, 128, "%+f %s", crosshair_1.value, signalcomp[i]->physdimension); painter->drawText((int)(((double)crosshair_1.x_position + 5.0) * printsize_x_factor), (int)(((double)crosshair_1.y_position - 40.0) * printsize_y_factor), string); snprintf(string, 128, "%2i:%02i:%02i.%04i", (int)(((crosshair_1.time / TIME_DIMENSION)/ 3600LL) % 24LL), (int)(((crosshair_1.time / TIME_DIMENSION) % 3600LL) / 60LL), (int)((crosshair_1.time / TIME_DIMENSION) % 60LL), (int)((crosshair_1.time % TIME_DIMENSION) / 1000LL)); painter->drawText((int)(((double)crosshair_1.x_position + 5.0) * printsize_x_factor), (int)(((double)crosshair_1.y_position - 25.0) * printsize_y_factor), string); if(signalcomp[i]->alias[0] != 0) { painter->drawText((int)(((double)crosshair_1.x_position + 5.0) * printsize_x_factor), (int)(((double)crosshair_1.y_position - 10.0) * printsize_y_factor), signalcomp[i]->alias); } else { painter->drawText((int)(((double)crosshair_1.x_position + 5.0) * printsize_x_factor), (int)(((double)crosshair_1.y_position - 10.0) * printsize_y_factor), signalcomp[i]->signallabel); } painter->setPen((Qt::GlobalColor)signalcomp[i]->color); } else { painter->setPen((Qt::GlobalColor)crosshair_1.color); painter->drawLine(0, crosshair_1.y_value, w, crosshair_1.y_value); painter->drawLine(crosshair_1.x_position, 0, crosshair_1.x_position, h); snprintf(string, 128, "%+f %s", crosshair_1.value, signalcomp[i]->physdimension); painter->drawText(crosshair_1.x_position + 5, crosshair_1.y_position - 40, string); snprintf(string, 128, "%2i:%02i:%02i.%04i", (int)(((crosshair_1.time / TIME_DIMENSION)/ 3600LL) % 24LL), (int)(((crosshair_1.time / TIME_DIMENSION) % 3600LL) / 60LL), (int)((crosshair_1.time / TIME_DIMENSION) % 60LL), (int)((crosshair_1.time % TIME_DIMENSION) / 1000LL)); snprintf(string + strlen(string), 32, " (%i:%02i:%02i.%04i)", (int)((crosshair_1.time_relative / TIME_DIMENSION)/ 3600LL), (int)(((crosshair_1.time_relative / TIME_DIMENSION) % 3600LL) / 60LL), (int)((crosshair_1.time_relative / TIME_DIMENSION) % 60LL), (int)((crosshair_1.time_relative % TIME_DIMENSION) / 1000LL)); painter->drawText(crosshair_1.x_position + 5, crosshair_1.y_position - 25, string); if(signalcomp[i]->alias[0] != 0) { painter->drawText(crosshair_1.x_position + 5, crosshair_1.y_position - 10, signalcomp[i]->alias); } else { painter->drawText(crosshair_1.x_position + 5, crosshair_1.y_position - 10, signalcomp[i]->signallabel); } painter->setPen((Qt::GlobalColor)signalcomp[i]->color); mainwindow->annotationEditDock->annotEditSetOnset(crosshair_1.time_relative); } } if(signalcomp[i]->hascursor2) { if(printing) { painter->setPen((Qt::GlobalColor)crosshair_2.color); painter->drawLine(0, crosshair_2.y_value, w, crosshair_2.y_value); painter->drawLine((int)((double)crosshair_2.x_position * printsize_x_factor), 0, (int)((double)crosshair_2.x_position * printsize_x_factor), h); snprintf(string, 128, "%+f %s", crosshair_2.value, signalcomp[i]->physdimension); painter->drawText((int)(((double)crosshair_2.x_position + 5.0) * printsize_x_factor), (int)(((double)crosshair_2.y_position - 70.0) * printsize_y_factor), string); snprintf(string, 128, "%2i:%02i:%02i.%04i", (int)(((crosshair_2.time / TIME_DIMENSION)/ 3600LL) % 24LL), (int)(((crosshair_2.time / TIME_DIMENSION) % 3600LL) / 60LL), (int)((crosshair_2.time / TIME_DIMENSION) % 60LL), (int)((crosshair_2.time % TIME_DIMENSION) / 1000LL)); painter->drawText((int)(((double)crosshair_2.x_position + 5.0) * printsize_x_factor), (int)(((double)crosshair_2.y_position - 55.0) * printsize_y_factor), string); snprintf(string, 128, "delta %+f %s", crosshair_2.value - crosshair_1.value, signalcomp[i]->physdimension); painter->drawText((int)(((double)crosshair_2.x_position + 5.0) * printsize_x_factor), (int)(((double)crosshair_2.y_position - 40.0) * printsize_y_factor), string); l_time = crosshair_2.time - crosshair_1.time; if(l_time<0) l_time = -l_time; snprintf(string, 128, "delta %i:%02i:%02i.%04i", (int)((l_time / TIME_DIMENSION)/ 3600LL), (int)(((l_time / TIME_DIMENSION) % 3600LL) / 60LL), (int)((l_time / TIME_DIMENSION) % 60LL), (int)((l_time % TIME_DIMENSION) / 1000LL)); painter->drawText((int)(((double)crosshair_2.x_position + 5.0) * printsize_x_factor), (int)(((double)crosshair_2.y_position - 25.0) * printsize_y_factor), string); if(signalcomp[i]->alias[0] != 0) { painter->drawText((int)(((double)crosshair_2.x_position + 5.0) * printsize_x_factor), (int)(((double)crosshair_2.y_position - 10.0) * printsize_y_factor), signalcomp[i]->alias); } else { painter->drawText((int)(((double)crosshair_2.x_position + 5.0) * printsize_x_factor), (int)(((double)crosshair_2.y_position - 10.0) * printsize_y_factor), signalcomp[i]->signallabel); } painter->setPen((Qt::GlobalColor)signalcomp[i]->color); } else { painter->setPen((Qt::GlobalColor)crosshair_2.color); painter->drawLine(0, crosshair_2.y_value, w, crosshair_2.y_value); painter->drawLine(crosshair_2.x_position, 0, crosshair_2.x_position, h); snprintf(string, 128, "%+f %s", crosshair_2.value, signalcomp[i]->physdimension); painter->drawText(crosshair_2.x_position + 5, crosshair_2.y_position - 70, string); snprintf(string, 128, "%2i:%02i:%02i.%04i", (int)(((crosshair_2.time / TIME_DIMENSION)/ 3600LL) % 24LL), (int)(((crosshair_2.time / TIME_DIMENSION) % 3600LL) / 60LL), (int)((crosshair_2.time / TIME_DIMENSION) % 60LL), (int)((crosshair_2.time % TIME_DIMENSION) / 1000LL)); snprintf(string + strlen(string), 32, " (%i:%02i:%02i.%04i)", (int)((crosshair_2.time_relative / TIME_DIMENSION)/ 3600LL), (int)(((crosshair_2.time_relative / TIME_DIMENSION) % 3600LL) / 60LL), (int)((crosshair_2.time_relative / TIME_DIMENSION) % 60LL), (int)((crosshair_2.time_relative % TIME_DIMENSION) / 1000LL)); painter->drawText(crosshair_2.x_position + 5, crosshair_2.y_position - 55, string); snprintf(string, 128, "delta %+f %s", crosshair_2.value - crosshair_1.value, signalcomp[i]->physdimension); painter->drawText(crosshair_2.x_position + 5, crosshair_2.y_position - 40, string); l_time = crosshair_2.time - crosshair_1.time; if(l_time<0) l_time = -l_time; snprintf(string, 128, "delta %i:%02i:%02i.%04i", (int)((l_time / TIME_DIMENSION)/ 3600LL), (int)(((l_time / TIME_DIMENSION) % 3600LL) / 60LL), (int)((l_time / TIME_DIMENSION) % 60LL), (int)((l_time % TIME_DIMENSION) / 1000LL)); painter->drawText(crosshair_2.x_position + 5, crosshair_2.y_position - 25, string); if(signalcomp[i]->alias[0] != 0) { painter->drawText(crosshair_2.x_position + 5, crosshair_2.y_position - 10, signalcomp[i]->alias); } else { painter->drawText(crosshair_2.x_position + 5, crosshair_2.y_position - 10, signalcomp[i]->signallabel); } painter->setPen((Qt::GlobalColor)signalcomp[i]->color); } } if(signalcomp[i]->hasoffsettracking) { snprintf(string, 128, "offset: %f %s", -signalcomp[i]->screen_offset * mainwindow->pixelsizefactor * signalcomp[i]->voltpercm, signalcomp[i]->physdimension); painter->fillRect(92, baseline, 190, 12, backgroundcolor); painter->setPen((Qt::GlobalColor)signalcomp[i]->color); painter->drawText(95, baseline + 10, string); } if(signalcomp[i]->hasgaintracking) { snprintf(string, 128, "gain: %f %s/cm", signalcomp[i]->voltpercm, signalcomp[i]->physdimension); painter->fillRect(92, baseline, 190, 12, backgroundcolor); painter->setPen((Qt::GlobalColor)signalcomp[i]->color); painter->drawText(95, baseline + 10, string); } } vertical_distance = h / (signalcomps + 1); for(i=0; ialias[0] != 0) { painter->fillRect(2, baseline - 20, strlen(signalcomp[i]->alias) * 7 + 6, 12, backgroundcolor); } else { painter->fillRect(2, baseline - 20, strlen(signalcomp[i]->signallabel) * 7 + 6, 12, backgroundcolor); } painter->setPen((Qt::GlobalColor)signalcomp[i]->color); if(signalcomp[i]->alias[0] != 0) { painter->drawText(5, baseline - 10, signalcomp[i]->alias); } else { painter->drawText(5, baseline - 10, signalcomp[i]->signallabel); } if(signalcomp[i]->hasruler) { floating_ruler(painter, ruler_x_position, ruler_y_position, signalcomp[i], print_linewidth); } } if(draw_zoom_rectangle) { special_pen->setColor(mouse_rect_color); painter->setPen(*special_pen); painter->drawRect(mouse_press_coordinate_x, mouse_press_coordinate_y, mouse_x - mouse_press_coordinate_x, mouse_y - mouse_press_coordinate_y); } painter->setPen(text_color); if(printing) { painter->drawText((int)(8.0 * printsize_y_factor), h - (int)(4.0 * printsize_y_factor), mainwindow->viewtime_string); painter->drawText(w - (int)(60.0 * printsize_y_factor), h - (int)(4.0 * printsize_y_factor), mainwindow->pagetime_string); } else { painter->fillRect(5, h - 14, 180, 12, backgroundcolor); painter->drawText(8, h - 4, mainwindow->viewtime_string); painter->fillRect(w - 63, h - 14, 60, 12, backgroundcolor); painter->drawText(w - 60, h - 4, mainwindow->pagetime_string); } } void ViewCurve::drawCurve_stage_1(QPainter *painter, int w_width, int w_height, int print_linewidth) { int i, j, k, n, x1, y1, x2, y2, signalcomps, baseline, value, minimum, maximum, runin_samples, stat_zero_crossing=0; char *viewbuf; long long s, s2; double dig_value=0.0, f_tmp=0.0; struct signalcompblock **signalcomp; union { unsigned int one; signed int one_signed; unsigned short two[2]; signed short two_signed[2]; unsigned char four[4]; } var; if(mainwindow->exit_in_progress) { if(graphicBuf!=NULL) { free(graphicBuf); graphicBuf = NULL; } return; } for(i=0; isignalcomps; signalcomp = mainwindow->signalcomp; viewbuf = mainwindow->viewbuf; painter_pixelsizefactor = 1.0 / mainwindow->pixelsizefactor; if(!w_width||!w_height) { w = width(); h = height(); printsize_x_factor = 1.0; printsize_y_factor = 1.0; printing = 0; } else { w = w_width; h = w_height; printsize_x_factor = ((double)w_width) / ((double)width()); printsize_y_factor = ((double)w_height) / ((double)height()); painter_pixelsizefactor *= printsize_y_factor; printing = 1; } for(i=0; isamples_on_screen < (w / 2)) { signalcomp[i]->sample_pixel_ratio = (((double)signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].smp_per_record / signalcomp[i]->edfhdr->data_record_duration) * ((double)mainwindow->pagetime / (double)TIME_DIMENSION)) / (double)w; } else { signalcomp[i]->sample_pixel_ratio = (double)signalcomp[i]->samples_on_screen / (double)w; } } if((viewbuf==NULL)||(screensamples==NULL)) { if(graphicBuf!=NULL) { free(graphicBuf); graphicBuf = NULL; } update(); return; } if((graphicBuf==NULL)||(graphicBufWidth!=w)) { if(graphicBuf!=NULL) { free(graphicBuf); } graphicBuf = (struct graphicBufStruct *)malloc(sizeof(struct graphicBufStruct) * w * 2 + 4); graphicBufWidth = w; } if(graphicBuf==NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "The system was not able to provide enough resources (memory) to perform the requested action."); messagewindow.exec(); return; } if(mainwindow->use_threads) { n = cpu_cnt; if(signalcomps < n) { n = signalcomps; } // for(i=0; iinit_vars(mainwindow, &signalcomp[0], i, signalcomps, viewbuf, w, h, &screensamples[0], printing, graphicBuf, printsize_x_factor, printsize_y_factor, &crosshair_1, &crosshair_2, cpu_cnt); thr[i]->start(); } for(i=0; iwait(); } } else { for(i=0; imax_dig_value = -2147483647; signalcomp[i]->min_dig_value = 2147483647; signalcomp[i]->stat_cnt = 0; signalcomp[i]->stat_zero_crossing_cnt = 0; signalcomp[i]->stat_sum = 0.0; signalcomp[i]->stat_sum_sqr = 0.0; signalcomp[i]->stat_sum_rectified = 0.0; baseline = h / (signalcomps + 1); baseline *= (i + 1); signalcomp[i]->pixels_shift = signalcomp[i]->sample_timeoffset_part / signalcomp[i]->sample_pixel_ratio; for(s=signalcomp[i]->sample_start; ssamples_on_screen; s++) { if(s>=signalcomp[i]->sample_stop) break; dig_value = 0.0; s2 = s + signalcomp[i]->sample_timeoffset - signalcomp[i]->sample_start; for(j=0; jnum_of_signals; j++) { if(signalcomp[i]->edfhdr->bdf) { var.two[0] = *((unsigned short *)( viewbuf + signalcomp[i]->viewbufoffset + (signalcomp[i]->edfhdr->recordsize * (s2 / signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[j]].smp_per_record)) + signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[j]].buf_offset + ((s2 % signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[j]].smp_per_record) * 3))); var.four[2] = *((unsigned char *)( viewbuf + signalcomp[i]->viewbufoffset + (signalcomp[i]->edfhdr->recordsize * (s2 / signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[j]].smp_per_record)) + signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[j]].buf_offset + ((s2 % signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[j]].smp_per_record) * 3) + 2)); if(var.four[2]&0x80) { var.four[3] = 0xff; } else { var.four[3] = 0x00; } f_tmp = var.one_signed; } if(signalcomp[i]->edfhdr->edf) { f_tmp = *(((short *)( viewbuf + signalcomp[i]->viewbufoffset + (signalcomp[i]->edfhdr->recordsize * (s2 / signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[j]].smp_per_record)) + signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[j]].buf_offset)) + (s2 % signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[j]].smp_per_record)); } f_tmp += signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[j]].offset; f_tmp *= signalcomp[i]->factor[j]; dig_value += f_tmp; } for(k=0; kfilter_cnt; k++) { if(s==signalcomp[i]->sample_start) { if(mainwindow->edfheaderlist[signalcomp[i]->filenum]->viewtime==0) { reset_filter(dig_value, signalcomp[i]->filter[k]); } else { signalcomp[i]->filter[k]->old_input = signalcomp[i]->filterpreset_a[k]; signalcomp[i]->filter[k]->old_output = signalcomp[i]->filterpreset_b[k]; } } dig_value = first_order_filter(dig_value, signalcomp[i]->filter[k]); } for(k=0; kravg_filter_cnt; k++) { if(s==signalcomp[i]->sample_start) { if((mainwindow->edfheaderlist[signalcomp[i]->filenum]->viewtime <= 0) && signalcomp[i]->ravg_filter_setup[k]) { reset_ravg_filter(dig_value, signalcomp[i]->ravg_filter[k]); } else { ravg_filter_restore_buf(signalcomp[i]->ravg_filter[k]); } signalcomp[i]->ravg_filter_setup[k] = 0; } dig_value = run_ravg_filter(dig_value, signalcomp[i]->ravg_filter[k]); } for(k=0; kfidfilter_cnt; k++) { if(s==signalcomp[i]->sample_start) { if((mainwindow->edfheaderlist[signalcomp[i]->filenum]->viewtime <= 0) && signalcomp[i]->fidfilter_setup[k]) { runin_samples = (signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].smp_per_record / signalcomp[i]->edfhdr->data_record_duration) / signalcomp[i]->fidfilter_freq[k]; runin_samples *= 26; if(runin_samples < 10) { runin_samples = 10; } for(n=0; nfidfuncp[k](signalcomp[i]->fidbuf[k], dig_value); } memcpy(signalcomp[i]->fidbuf2[k], signalcomp[i]->fidbuf[k], fid_run_bufsize(signalcomp[i]->fid_run[k])); } else { memcpy(signalcomp[i]->fidbuf[k], signalcomp[i]->fidbuf2[k], fid_run_bufsize(signalcomp[i]->fid_run[k])); } signalcomp[i]->fidfilter_setup[k] = 0; } dig_value = signalcomp[i]->fidfuncp[k](signalcomp[i]->fidbuf[k], dig_value); } if(signalcomp[i]->ecg_filter != NULL) { if(s==signalcomp[i]->sample_start) { if(mainwindow->edfheaderlist[signalcomp[i]->filenum]->viewtime <= 0LL) { reset_ecg_filter(signalcomp[i]->ecg_filter); } else { ecg_filter_restore_buf(signalcomp[i]->ecg_filter); } } dig_value = run_ecg_filter(dig_value, signalcomp[i]->ecg_filter); } if(signalcomp[i]->zratio_filter != NULL) { if(s==signalcomp[i]->sample_start) { if(mainwindow->edfheaderlist[signalcomp[i]->filenum]->viewtime <= 0LL) { reset_zratio_filter(signalcomp[i]->zratio_filter); } else { zratio_filter_restore_buf(signalcomp[i]->zratio_filter); } } dig_value = run_zratio_filter(dig_value, signalcomp[i]->zratio_filter); } if(printing) { value = (int)(dig_value * signalcomp[i]->sensitivity[0] * printsize_y_factor) * signalcomp[i]->polarity; } else { value = (int)(dig_value * signalcomp[i]->sensitivity[0]) * signalcomp[i]->polarity; signalcomp[i]->stat_cnt++; signalcomp[i]->stat_sum += dig_value; signalcomp[i]->stat_sum_sqr += ((dig_value) * (dig_value)); if(dig_value < 0) { signalcomp[i]->stat_sum_rectified += (dig_value * -1.0); } else { signalcomp[i]->stat_sum_rectified += dig_value; } if(s==signalcomp[i]->sample_start) { if(dig_value < 0.0) { stat_zero_crossing = 0; } else { stat_zero_crossing = 1; } } else { if(dig_value < 0.0) { if(stat_zero_crossing) { stat_zero_crossing = 0; signalcomp[i]->stat_zero_crossing_cnt++; } } else { if(!stat_zero_crossing) { stat_zero_crossing = 1; signalcomp[i]->stat_zero_crossing_cnt++; } } } } if(((int)dig_value)>signalcomp[i]->max_dig_value) signalcomp[i]->max_dig_value = dig_value; if(((int)dig_value)min_dig_value) signalcomp[i]->min_dig_value = dig_value; if(printing) { value = baseline - value + (int)(signalcomp[i]->screen_offset * printsize_y_factor); } else { value = baseline - value + signalcomp[i]->screen_offset; } if(s>=signalcomp[i]->sample_start) { x1 = (int)((double)s / signalcomp[i]->sample_pixel_ratio); y1 = signalcomp[i]->oldvalue; x2 = (int)(((double)s + 1.0) / signalcomp[i]->sample_pixel_ratio); y2 = value; if(signalcomp[i]->samples_on_screen < (w / 2)) { graphicBuf[screensamples[i]].graphicLine[i].x1 = x1 - signalcomp[i]->pixels_shift; graphicBuf[screensamples[i]].graphicLine[i].y1 = y2; graphicBuf[screensamples[i]].graphicLine[i].x2 = x2 - signalcomp[i]->pixels_shift; graphicBuf[screensamples[i]].graphicLine[i].y2 = y2; if(screensamples[i]) { screensamples[i]++; graphicBuf[screensamples[i]].graphicLine[i].x1 = x1 - signalcomp[i]->pixels_shift; graphicBuf[screensamples[i]].graphicLine[i].y1 = y1; graphicBuf[screensamples[i]].graphicLine[i].x2 = x1 - signalcomp[i]->pixels_shift; graphicBuf[screensamples[i]].graphicLine[i].y2 = y2; } screensamples[i]++; } else { if(!screensamples[i]) { graphicBuf[screensamples[i]].graphicLine[i].x1 = x1; graphicBuf[screensamples[i]].graphicLine[i].y1 = y1; graphicBuf[screensamples[i]].graphicLine[i].x2 = x2; graphicBuf[screensamples[i]].graphicLine[i].y2 = y2; screensamples[i]++; } else { if((x1==x2)&&(x1==graphicBuf[screensamples[i]-1].graphicLine[i].x1)&& (graphicBuf[screensamples[i]-1].graphicLine[i].x1==graphicBuf[screensamples[i]-1].graphicLine[i].x2)) { maximum = y1; if(y2>maximum) maximum = y2; if(graphicBuf[screensamples[i]-1].graphicLine[i].y1>maximum) maximum = graphicBuf[screensamples[i]-1].graphicLine[i].y1; if(graphicBuf[screensamples[i]-1].graphicLine[i].y2>maximum) maximum = graphicBuf[screensamples[i]-1].graphicLine[i].y2; minimum = y1; if(y2oldvalue = value; if(signalcomp[i]->hascursor1) { if(printing) { if(s==((int)((double)(crosshair_1.x_position * printsize_x_factor + (double)signalcomp[i]->pixels_shift) * signalcomp[i]->sample_pixel_ratio))) { crosshair_1.y_value = value; crosshair_1.value = dig_value * signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].bitvalue; crosshair_1.time = mainwindow->edfheaderlist[signalcomp[i]->filenum]->l_starttime + mainwindow->edfheaderlist[signalcomp[i]->filenum]->viewtime + signalcomp[i]->edfhdr->starttime_offset + (long long)(((double)mainwindow->pagetime / ((double)w / printsize_x_factor)) * (double)crosshair_1.x_position); crosshair_1.time_relative = mainwindow->edfheaderlist[signalcomp[i]->filenum]->viewtime + (long long)(((double)mainwindow->pagetime / ((double)w / printsize_x_factor)) * (double)crosshair_1.x_position); } } else { if(s==((int)((double)(crosshair_1.x_position + signalcomp[i]->pixels_shift) * signalcomp[i]->sample_pixel_ratio))) { crosshair_1.y_value = value; crosshair_1.value = dig_value * signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].bitvalue; crosshair_1.time = mainwindow->edfheaderlist[signalcomp[i]->filenum]->l_starttime + mainwindow->edfheaderlist[signalcomp[i]->filenum]->viewtime + signalcomp[i]->edfhdr->starttime_offset + (long long)(((double)mainwindow->pagetime / (double)w) * (double)crosshair_1.x_position); crosshair_1.time_relative = mainwindow->edfheaderlist[signalcomp[i]->filenum]->viewtime + (long long)(((double)mainwindow->pagetime / (double)w) * (double)crosshair_1.x_position); } } } if(signalcomp[i]->hascursor2) { if(printing) { if(s==((int)((double)(crosshair_2.x_position * printsize_x_factor + (double)signalcomp[i]->pixels_shift) * signalcomp[i]->sample_pixel_ratio))) { crosshair_2.y_value = value; crosshair_2.value = dig_value * signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].bitvalue; crosshair_2.time = mainwindow->edfheaderlist[signalcomp[i]->filenum]->l_starttime + mainwindow->edfheaderlist[signalcomp[i]->filenum]->viewtime + signalcomp[i]->edfhdr->starttime_offset + (long long)(((double)mainwindow->pagetime / ((double)w / printsize_x_factor)) * (double)crosshair_2.x_position); crosshair_2.time_relative = mainwindow->edfheaderlist[signalcomp[i]->filenum]->viewtime + (long long)(((double)mainwindow->pagetime / ((double)w / printsize_x_factor)) * (double)crosshair_2.x_position); } } else { if(s==((int)((double)(crosshair_2.x_position + signalcomp[i]->pixels_shift) * signalcomp[i]->sample_pixel_ratio))) { crosshair_2.y_value = value; crosshair_2.value = dig_value * signalcomp[i]->edfhdr->edfparam[signalcomp[i]->edfsignal[0]].bitvalue; crosshair_2.time = mainwindow->edfheaderlist[signalcomp[i]->filenum]->l_starttime + mainwindow->edfheaderlist[signalcomp[i]->filenum]->viewtime + signalcomp[i]->edfhdr->starttime_offset + (long long)(((double)mainwindow->pagetime / (double)w) * (double)crosshair_2.x_position); crosshair_2.time_relative = mainwindow->edfheaderlist[signalcomp[i]->filenum]->viewtime + (long long)(((double)mainwindow->pagetime / (double)w) * (double)crosshair_2.x_position); } } } } } } if(printing) { drawCurve_stage_2(painter, w_width, w_height, print_linewidth); } else { update(); } } void drawCurve_stage_1_thread::init_vars(UI_Mainwindow *mainwindow_a, struct signalcompblock **signalcomp_a, int i_a, int signalcomps_a, char *viewbuf_a, int w_a, int h_a, int *screensamples_a, int printing_a, struct graphicBufStruct *graphicBuf_a, double printsize_x_factor_a, double printsize_y_factor_a, struct crossHairStruct *crosshair_1_a, struct crossHairStruct *crosshair_2_a, int cpu_cnt_a) { mainwindow = mainwindow_a; signalcomp_b = signalcomp_a; i = i_a; signalcomps = signalcomps_a; viewbuf = viewbuf_a; w = w_a; h = h_a; screensamples_b = screensamples_a; printing = printing_a; graphicBuf = graphicBuf_a; printsize_x_factor = printsize_x_factor_a; printsize_y_factor = printsize_y_factor_a; crosshair_1 = crosshair_1_a; crosshair_2 = crosshair_2_a; cpu_cnt = cpu_cnt_a; // printf("init_vars(): i is %i signalcomp_b is %08X screensamples_b is %08X\n------------------------\n", // i, (int)signalcomp_b[i], (int)screensamples_b); } void drawCurve_stage_1_thread::run() { int j, k, n, x1, y1, x2, y2, baseline, value, minimum, maximum, runin_samples, stat_zero_crossing; long long s, s2; double dig_value, f_tmp; union { unsigned int one; signed int one_signed; unsigned short two[2]; signed short two_signed[2]; unsigned char four[4]; } var; for(; i < signalcomps; i += cpu_cnt) { // printf("i is %i cpu_cnt is %i\n", i, cpu_cnt); screensamples = &screensamples_b[i]; signalcomp = signalcomp_b[i]; // printf("i is %i signalcomp is %08X screensamples is %08X\n", // i, (int)signalcomp, (int)screensamples); f_tmp = 0.0; dig_value=0.0; stat_zero_crossing=0; signalcomp->max_dig_value = -2147483647; signalcomp->min_dig_value = 2147483647; signalcomp->stat_cnt = 0; signalcomp->stat_zero_crossing_cnt = 0; signalcomp->stat_sum = 0.0; signalcomp->stat_sum_sqr = 0.0; signalcomp->stat_sum_rectified = 0.0; baseline = h / (signalcomps + 1); baseline *= (i + 1); signalcomp->pixels_shift = signalcomp->sample_timeoffset_part / signalcomp->sample_pixel_ratio; for(s=signalcomp->sample_start; ssamples_on_screen; s++) { if(s>=signalcomp->sample_stop) break; dig_value = 0.0; s2 = s + signalcomp->sample_timeoffset - signalcomp->sample_start; for(j=0; jnum_of_signals; j++) { if(signalcomp->edfhdr->bdf) { var.two[0] = *((unsigned short *)( viewbuf + signalcomp->viewbufoffset + (signalcomp->edfhdr->recordsize * (s2 / signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].smp_per_record)) + signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].buf_offset + ((s2 % signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].smp_per_record) * 3))); var.four[2] = *((unsigned char *)( viewbuf + signalcomp->viewbufoffset + (signalcomp->edfhdr->recordsize * (s2 / signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].smp_per_record)) + signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].buf_offset + ((s2 % signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].smp_per_record) * 3) + 2)); if(var.four[2]&0x80) { var.four[3] = 0xff; } else { var.four[3] = 0x00; } f_tmp = var.one_signed; } if(signalcomp->edfhdr->edf) { f_tmp = *(((short *)( viewbuf + signalcomp->viewbufoffset + (signalcomp->edfhdr->recordsize * (s2 / signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].smp_per_record)) + signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].buf_offset)) + (s2 % signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].smp_per_record)); } f_tmp += signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].offset; f_tmp *= signalcomp->factor[j]; dig_value += f_tmp; } for(k=0; kfilter_cnt; k++) { if(s==signalcomp->sample_start) { if(mainwindow->edfheaderlist[signalcomp->filenum]->viewtime==0) { reset_filter(dig_value, signalcomp->filter[k]); } else { signalcomp->filter[k]->old_input = signalcomp->filterpreset_a[k]; signalcomp->filter[k]->old_output = signalcomp->filterpreset_b[k]; } } dig_value = first_order_filter(dig_value, signalcomp->filter[k]); } for(k=0; kravg_filter_cnt; k++) { if(s==signalcomp->sample_start) { if((mainwindow->edfheaderlist[signalcomp->filenum]->viewtime <= 0) && signalcomp->ravg_filter_setup[k]) { reset_ravg_filter(dig_value, signalcomp->ravg_filter[k]); } else { ravg_filter_restore_buf(signalcomp->ravg_filter[k]); } signalcomp->ravg_filter_setup[k] = 0; } dig_value = run_ravg_filter(dig_value, signalcomp->ravg_filter[k]); } for(k=0; kfidfilter_cnt; k++) { if(s==signalcomp->sample_start) { if((mainwindow->edfheaderlist[signalcomp->filenum]->viewtime <= 0) && signalcomp->fidfilter_setup[k]) { runin_samples = (signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].smp_per_record / signalcomp->edfhdr->data_record_duration) / signalcomp->fidfilter_freq[k]; runin_samples *= 26; if(runin_samples < 10) { runin_samples = 10; } for(n=0; nfidfuncp[k](signalcomp->fidbuf[k], dig_value); } memcpy(signalcomp->fidbuf2[k], signalcomp->fidbuf[k], fid_run_bufsize(signalcomp->fid_run[k])); } else { memcpy(signalcomp->fidbuf[k], signalcomp->fidbuf2[k], fid_run_bufsize(signalcomp->fid_run[k])); } signalcomp->fidfilter_setup[k] = 0; } dig_value = signalcomp->fidfuncp[k](signalcomp->fidbuf[k], dig_value); } if(signalcomp->ecg_filter != NULL) { if(s==signalcomp->sample_start) { if(mainwindow->edfheaderlist[signalcomp->filenum]->viewtime <= 0LL) { reset_ecg_filter(signalcomp->ecg_filter); } else { ecg_filter_restore_buf(signalcomp->ecg_filter); } } dig_value = run_ecg_filter(dig_value, signalcomp->ecg_filter); } if(signalcomp->zratio_filter != NULL) { if(s==signalcomp->sample_start) { if(mainwindow->edfheaderlist[signalcomp->filenum]->viewtime <= 0LL) { reset_zratio_filter(signalcomp->zratio_filter); } else { zratio_filter_restore_buf(signalcomp->zratio_filter); } } dig_value = run_zratio_filter(dig_value, signalcomp->zratio_filter); } if(printing) { value = (int)(dig_value * signalcomp->sensitivity[0] * printsize_y_factor) * signalcomp->polarity; } else { value = (int)(dig_value * signalcomp->sensitivity[0]) * signalcomp->polarity; signalcomp->stat_cnt++; signalcomp->stat_sum += dig_value; signalcomp->stat_sum_sqr += ((dig_value) * (dig_value)); if(dig_value < 0) { signalcomp->stat_sum_rectified += (dig_value * -1.0); } else { signalcomp->stat_sum_rectified += dig_value; } if(s==signalcomp->sample_start) { if(dig_value < 0.0) { stat_zero_crossing = 0; } else { stat_zero_crossing = 1; } } else { if(dig_value < 0.0) { if(stat_zero_crossing) { stat_zero_crossing = 0; signalcomp->stat_zero_crossing_cnt++; } } else { if(!stat_zero_crossing) { stat_zero_crossing = 1; signalcomp->stat_zero_crossing_cnt++; } } } } if(dig_value > signalcomp->max_dig_value) signalcomp->max_dig_value = dig_value; if(dig_value < signalcomp->min_dig_value) signalcomp->min_dig_value = dig_value; if(printing) { value = baseline - value + (int)(signalcomp->screen_offset * printsize_y_factor); } else { value = baseline - value + signalcomp->screen_offset; } if(s>=signalcomp->sample_start) { x1 = (int)((double)s / signalcomp->sample_pixel_ratio); y1 = signalcomp->oldvalue; x2 = (int)(((double)s + 1.0) / signalcomp->sample_pixel_ratio); y2 = value; if(signalcomp->samples_on_screen < (w / 2)) { graphicBuf[*screensamples].graphicLine[i].x1 = x1 - signalcomp->pixels_shift; graphicBuf[*screensamples].graphicLine[i].y1 = y2; graphicBuf[*screensamples].graphicLine[i].x2 = x2 - signalcomp->pixels_shift; graphicBuf[*screensamples].graphicLine[i].y2 = y2; if(*screensamples) { (*screensamples)++; graphicBuf[*screensamples].graphicLine[i].x1 = x1 - signalcomp->pixels_shift; graphicBuf[*screensamples].graphicLine[i].y1 = y1; graphicBuf[*screensamples].graphicLine[i].x2 = x1 - signalcomp->pixels_shift; graphicBuf[*screensamples].graphicLine[i].y2 = y2; } (*screensamples)++; } else { if(!(*screensamples)) { graphicBuf[*screensamples].graphicLine[i].x1 = x1; graphicBuf[*screensamples].graphicLine[i].y1 = y1; graphicBuf[*screensamples].graphicLine[i].x2 = x2; graphicBuf[*screensamples].graphicLine[i].y2 = y2; (*screensamples)++; } else { if((x1==x2)&&(x1==graphicBuf[(*screensamples)-1].graphicLine[i].x1)&& (graphicBuf[(*screensamples)-1].graphicLine[i].x1==graphicBuf[(*screensamples)-1].graphicLine[i].x2)) { maximum = y1; if(y2>maximum) maximum = y2; if(graphicBuf[(*screensamples)-1].graphicLine[i].y1>maximum) maximum = graphicBuf[(*screensamples)-1].graphicLine[i].y1; if(graphicBuf[(*screensamples)-1].graphicLine[i].y2>maximum) maximum = graphicBuf[(*screensamples)-1].graphicLine[i].y2; minimum = y1; if(y2oldvalue = value; if(signalcomp->hascursor1) { if(printing) { if(s==((int)((double)(crosshair_1->x_position * printsize_x_factor + (double)signalcomp->pixels_shift) * signalcomp->sample_pixel_ratio))) { crosshair_1->y_value = value; crosshair_1->value = dig_value * signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].bitvalue; crosshair_1->time = mainwindow->edfheaderlist[signalcomp->filenum]->l_starttime + mainwindow->edfheaderlist[signalcomp->filenum]->viewtime + signalcomp->edfhdr->starttime_offset + (long long)(((double)mainwindow->pagetime / ((double)w / printsize_x_factor)) * (double)crosshair_1->x_position); crosshair_1->time_relative = mainwindow->edfheaderlist[signalcomp->filenum]->viewtime + (long long)(((double)mainwindow->pagetime / ((double)w / printsize_x_factor)) * (double)crosshair_1->x_position); } } else { if(s==((int)((double)(crosshair_1->x_position + signalcomp->pixels_shift) * signalcomp->sample_pixel_ratio))) { crosshair_1->y_value = value; crosshair_1->value = dig_value * signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].bitvalue; crosshair_1->time = mainwindow->edfheaderlist[signalcomp->filenum]->l_starttime + mainwindow->edfheaderlist[signalcomp->filenum]->viewtime + signalcomp->edfhdr->starttime_offset + (long long)(((double)mainwindow->pagetime / (double)w) * (double)crosshair_1->x_position); crosshair_1->time_relative = mainwindow->edfheaderlist[signalcomp->filenum]->viewtime + (long long)(((double)mainwindow->pagetime / (double)w) * (double)crosshair_1->x_position); } } } if(signalcomp->hascursor2) { if(printing) { if(s==((int)((double)(crosshair_2->x_position * printsize_x_factor + (double)signalcomp->pixels_shift) * signalcomp->sample_pixel_ratio))) { crosshair_2->y_value = value; crosshair_2->value = dig_value * signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].bitvalue; crosshair_2->time = mainwindow->edfheaderlist[signalcomp->filenum]->l_starttime + mainwindow->edfheaderlist[signalcomp->filenum]->viewtime + signalcomp->edfhdr->starttime_offset + (long long)(((double)mainwindow->pagetime / ((double)w / printsize_x_factor)) * (double)crosshair_2->x_position); crosshair_2->time_relative = mainwindow->edfheaderlist[signalcomp->filenum]->viewtime + (long long)(((double)mainwindow->pagetime / ((double)w / printsize_x_factor)) * (double)crosshair_2->x_position); } } else { if(s==((int)((double)(crosshair_2->x_position + signalcomp->pixels_shift) * signalcomp->sample_pixel_ratio))) { crosshair_2->y_value = value; crosshair_2->value = dig_value * signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].bitvalue; crosshair_2->time = mainwindow->edfheaderlist[signalcomp->filenum]->l_starttime + mainwindow->edfheaderlist[signalcomp->filenum]->viewtime + signalcomp->edfhdr->starttime_offset + (long long)(((double)mainwindow->pagetime / (double)w) * (double)crosshair_2->x_position); crosshair_2->time_relative = mainwindow->edfheaderlist[signalcomp->filenum]->viewtime + (long long)(((double)mainwindow->pagetime / (double)w) * (double)crosshair_2->x_position); } } } } } } void ViewCurve::exec_sidemenu(int signal_nr_intern) { int i; char str[32]={0,0,0,0,0,0}; signal_nr = signal_nr_intern; sidemenu = new QDialog(this); sidemenu->setMinimumSize(QSize(190, 460)); sidemenu->setMaximumSize(QSize(190, 460)); sidemenu->setWindowTitle("Signal"); sidemenu->setModal(TRUE); sidemenu->setAttribute(Qt::WA_DeleteOnClose, TRUE); SidemenuLabel = new QLabel(sidemenu); SidemenuLabel->setGeometry(QRect(45, 5, 100, 20)); SidemenuLabel->setText(mainwindow->signalcomp[signal_nr]->signallabel); AliasLabel = new QLabel(sidemenu); AliasLabel->setGeometry(5, 30, 35, 20); AliasLabel->setText("Alias"); AliasLineEdit = new QLineEdit(sidemenu); AliasLineEdit->setGeometry(45, 30, 140, 20); AliasLineEdit->setText(mainwindow->signalcomp[signal_nr]->alias); AliasLineEdit->setMaxLength(16); AmpLabel = new QLabel(sidemenu); AmpLabel->setGeometry(QRect(5, 55, 35, 20)); AmpLabel->setText("Ampl."); OffsetLabel = new QLabel(sidemenu); OffsetLabel->setGeometry(QRect(5, 80, 35, 20)); OffsetLabel->setText("Offset"); ScaleBox = new QDoubleSpinBox(sidemenu); ScaleBox->setGeometry(QRect(45, 55, 140, 20)); ScaleBox->setDecimals(8); ScaleBox->setMaximum(1000000.0); ScaleBox->setMinimum(0.0000001); if(mainwindow->signalcomp[signal_nr]->edfhdr->edfparam[mainwindow->signalcomp[signal_nr]->edfsignal[0]].bitvalue < 0.0) { ScaleBox->setValue(mainwindow->signalcomp[signal_nr]->voltpercm * -1.0); } else { ScaleBox->setValue(mainwindow->signalcomp[signal_nr]->voltpercm); } strcpy(str, mainwindow->signalcomp[signal_nr]->physdimension); for(i=1; i<4; i++) { if(str[i]==' ') break; } strcpy(str + i, "/cm"); ScaleBox->setSuffix(str); ScaleBox2 = new QDoubleSpinBox(sidemenu); ScaleBox2->setGeometry(QRect(45, 80, 140, 20)); ScaleBox2->setDecimals(8); ScaleBox2->setMaximum(1000000.0); ScaleBox2->setMinimum(-1000000.0); ScaleBox2->setValue(-mainwindow->signalcomp[signal_nr]->screen_offset * mainwindow->pixelsizefactor * mainwindow->signalcomp[signal_nr]->voltpercm); ScaleBox2->setSuffix(mainwindow->signalcomp[signal_nr]->physdimension); sidemenuButton1 = new QPushButton(sidemenu); sidemenuButton1->setGeometry(QRect(45, 105, 100, 20)); sidemenuButton1->setText("Ruler"); sidemenuButton2 = new QPushButton(sidemenu); sidemenuButton2->setGeometry(QRect(45, 130, 100, 20)); sidemenuButton2->setText("Crosshair"); sidemenuButton3 = new QPushButton(sidemenu); sidemenuButton3->setGeometry(QRect(45, 155, 100, 20)); sidemenuButton3->setText("Fit to pane"); sidemenuButton4 = new QPushButton(sidemenu); sidemenuButton4->setGeometry(QRect(45, 180, 100, 20)); sidemenuButton4->setText("Color"); sidemenuButton5 = new QPushButton(sidemenu); sidemenuButton5->setGeometry(QRect(45, 205, 100, 20)); sidemenuButton5->setText("Invert"); sidemenuButton6 = new QPushButton(sidemenu); sidemenuButton6->setGeometry(QRect(45, 230, 100, 20)); sidemenuButton6->setText("Spectrum"); sidemenuButton7 = new QPushButton(sidemenu); sidemenuButton7->setGeometry(QRect(45, 255, 100, 20)); sidemenuButton7->setText("Z-EEG"); sidemenuButton8 = new QPushButton(sidemenu); sidemenuButton8->setGeometry(QRect(45, 280, 100, 20)); sidemenuButton8->setText("Remove filter"); sidemenuButton9 = new QPushButton(sidemenu); sidemenuButton9->setGeometry(QRect(45, 305, 100, 20)); sidemenuButton9->setText("Remove signal"); sidemenuButton10 = new QPushButton(sidemenu); sidemenuButton10->setGeometry(QRect(45, 330, 100, 20)); sidemenuButton10->setText("Adjust filter"); sidemenuButton11 = new QPushButton(sidemenu); sidemenuButton11->setGeometry(QRect(45, 355, 100, 20)); sidemenuButton11->setText("Statistics"); sidemenuButton12 = new QPushButton(sidemenu); sidemenuButton12->setGeometry(QRect(45, 380, 100, 20)); sidemenuButton12->setText("Heart Rate"); sidemenuButton13 = new QPushButton(sidemenu); sidemenuButton13->setGeometry(QRect(45, 405, 100, 20)); sidemenuButton13->setText("Close"); QObject::connect(ScaleBox, SIGNAL(valueChanged(double)), this, SLOT(ScaleBoxChanged(double))); QObject::connect(ScaleBox2, SIGNAL(valueChanged(double)), this, SLOT(ScaleBox2Changed(double))); QObject::connect(sidemenuButton1, SIGNAL(clicked()), this, SLOT(RulerButton())); QObject::connect(sidemenuButton2, SIGNAL(clicked()), this, SLOT(CrosshairButton())); QObject::connect(sidemenuButton3, SIGNAL(clicked()), this, SLOT(FittopaneButton())); QObject::connect(sidemenuButton4, SIGNAL(clicked()), this, SLOT(ColorButton())); QObject::connect(sidemenuButton5, SIGNAL(clicked()), this, SLOT(signalInvert())); QObject::connect(sidemenuButton6, SIGNAL(clicked()), this, SLOT(FreqSpecButton())); QObject::connect(sidemenuButton7, SIGNAL(clicked()), this, SLOT(Z_scoringButton())); QObject::connect(sidemenuButton8, SIGNAL(clicked()), this, SLOT(RemovefilterButton())); QObject::connect(sidemenuButton9, SIGNAL(clicked()), this, SLOT(RemovesignalButton())); QObject::connect(sidemenuButton10, SIGNAL(clicked()), this, SLOT(AdjustFilterButton())); QObject::connect(sidemenuButton11, SIGNAL(clicked()), this, SLOT(StatisticsButton())); QObject::connect(sidemenuButton12, SIGNAL(clicked()), this, SLOT(ECGdetectButton())); QObject::connect(sidemenuButton13, SIGNAL(clicked()), this, SLOT(sidemenu_close())); QObject::connect(AliasLineEdit, SIGNAL(returnPressed()), this, SLOT(sidemenu_close())); sidemenu->exec(); } void ViewCurve::sidemenu_close() { if(AliasLineEdit->isModified() == true) { strncpy(mainwindow->signalcomp[signal_nr]->alias, AliasLineEdit->text().toLatin1().data(), 16); mainwindow->signalcomp[signal_nr]->alias[16] = 0; latin1_to_ascii(mainwindow->signalcomp[signal_nr]->alias, 16); remove_trailing_spaces(mainwindow->signalcomp[signal_nr]->alias); remove_leading_spaces(mainwindow->signalcomp[signal_nr]->alias); } sidemenu->close(); } void ViewCurve::signalInvert() { sidemenu->close(); if(!mainwindow->signalcomps) { return; } if(signal_nr>(mainwindow->signalcomps - 1)) { return; } if(mainwindow->signalcomp[signal_nr]->polarity != 1) { mainwindow->signalcomp[signal_nr]->polarity = 1; } else { mainwindow->signalcomp[signal_nr]->polarity = -1; } mainwindow->setup_viewbuf(); } void ViewCurve::ECGdetectButton() { int i; struct signalcompblock *newsignalcomp; sidemenu->close(); if(!mainwindow->signalcomps) { return; } if(signal_nr>(mainwindow->signalcomps - 1)) { return; } if(mainwindow->signalcomp[signal_nr]->zratio_filter != NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Z-ratio is active for this signal!"); messagewindow.exec(); return; } if(mainwindow->signalcomp[signal_nr]->ecg_filter != NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Heartrate detection is already active for this signal!"); messagewindow.exec(); return; } newsignalcomp = mainwindow->create_signalcomp_copy(mainwindow->signalcomp[signal_nr]); if(newsignalcomp == NULL) { return; } newsignalcomp->ecg_filter = create_ecg_filter(newsignalcomp->edfhdr->edfparam[newsignalcomp->edfsignal[0]].smp_per_record / newsignalcomp->edfhdr->data_record_duration, newsignalcomp->edfhdr->edfparam[newsignalcomp->edfsignal[0]].bitvalue, mainwindow->powerlinefreq); strcpy(newsignalcomp->signallabel_bu, newsignalcomp->signallabel); newsignalcomp->signallabellen_bu = newsignalcomp->signallabellen; strcpy(newsignalcomp->signallabel, "HR"); newsignalcomp->signallabellen = strlen(newsignalcomp->signallabel); strcpy(newsignalcomp->physdimension_bu, newsignalcomp->physdimension); strcpy(newsignalcomp->physdimension, "bpm"); newsignalcomp->alias[0] = 0; if(newsignalcomp->edfhdr->edfparam[newsignalcomp->edfsignal[0]].bitvalue < 0.0) { for(i=0; inum_of_signals; i++) { newsignalcomp->sensitivity[i] = newsignalcomp->edfhdr->edfparam[newsignalcomp->edfsignal[i]].bitvalue / -5.0 / mainwindow->pixelsizefactor; } newsignalcomp->voltpercm = -5.0; } else { for(i=0; inum_of_signals; i++) { newsignalcomp->sensitivity[i] = newsignalcomp->edfhdr->edfparam[newsignalcomp->edfsignal[i]].bitvalue / 5.0 / mainwindow->pixelsizefactor; } newsignalcomp->voltpercm = 5.0; } newsignalcomp->screen_offset = 55.0 / (mainwindow->pixelsizefactor * newsignalcomp->voltpercm); mainwindow->setup_viewbuf(); } void ViewCurve::AdjustFilterButton() { sidemenu->close(); if(!mainwindow->signalcomps) { return; } if(signal_nr>(mainwindow->signalcomps - 1)) { return; } AdjustFilterSettings filtersettings(mainwindow->signalcomp[signal_nr], this); } void ViewCurve::StatisticsButton() { if(!mainwindow->signalcomps) { sidemenu->close(); return; } if(signal_nr>(mainwindow->signalcomps - 1)) { sidemenu->close(); return; } sidemenu->close(); UI_StatisticWindow show_stats_window(mainwindow->signalcomp[signal_nr], mainwindow->pagetime); } void ViewCurve::FreqSpecButton() { int i, j; for(i=0; ispectrumdialog[i] == NULL) { mainwindow->spectrumdialog[i] = new UI_FreqSpectrumWindow(mainwindow->signalcomp[signal_nr], mainwindow->viewbuf, mainwindow->spectrumdialog, i, mainwindow); break; } } sidemenu->close(); if(isignalcomp[signal_nr]->spectr_dialog[j] == 0) { mainwindow->signalcomp[signal_nr]->spectr_dialog[j] = i + 1; break; } } mainwindow->spectrumdialog[i]->SpectrumDialog->move(((i % 15) * 30) + 200, ((i % 15) * 30) + 200); for(j=0; jspectrumdialog[j] != NULL) { mainwindow->spectrumdialog[j]->SpectrumDialog->raise(); } } mainwindow->spectrumdialog[i]->SpectrumDialog->activateWindow(); mainwindow->spectrumdialog[i]->SpectrumDialog->raise(); } } void ViewCurve::Z_scoringButton() { int i, j; if(mainwindow->signalcomp[signal_nr]->ecg_filter != NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Heartrate detection is active for this signal!"); messagewindow.exec(); return; } if(mainwindow->signalcomp[signal_nr]->zratio_filter != NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Z-ratio is already active for this signal!"); messagewindow.exec(); return; } if(mainwindow->annot_editor_active) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Close the annotation editor and try again."); messagewindow.exec(); return; } for(i=0; izscoredialog[i] == NULL) { mainwindow->zscoredialog[i] = new UI_ZScoreWindow(mainwindow, mainwindow->zscoredialog, i, signal_nr); break; } } sidemenu->close(); if(isignalcomp[signal_nr]->zscoredialog[j] == 0) { mainwindow->signalcomp[signal_nr]->zscoredialog[j] = i + 1; break; } } mainwindow->zscoredialog[i]->zscore_dialog->move(((i % 15) * 30) + 200, ((i % 15) * 30) + 200); for(j=0; jzscoredialog[j] != NULL) { mainwindow->zscoredialog[j]->zscore_dialog->raise(); } } mainwindow->zscoredialog[i]->zscore_dialog->activateWindow(); mainwindow->zscoredialog[i]->zscore_dialog->raise(); } } void ViewCurve::FittopaneButton() { int j, pane_size, signalcomps; struct signalcompblock **signalcomp; signalcomps = mainwindow->signalcomps; signalcomp = mainwindow->signalcomp; if(!signalcomps) { sidemenu->close(); return; } if(signal_nr>(signalcomps - 1)) { sidemenu->close(); return; } pane_size = (int)(((double)height() * 0.95) / signalcomps); for(j=0; jnum_of_signals; j++) { if(signalcomp[signal_nr]->max_dig_value!=signalcomp[signal_nr]->min_dig_value) { signalcomp[signal_nr]->sensitivity[j] = (double)pane_size / (double)(signalcomp[signal_nr]->max_dig_value - signalcomp[signal_nr]->min_dig_value); } else { signalcomp[signal_nr]->sensitivity[j] = pane_size; } signalcomp[signal_nr]->voltpercm = signalcomp[signal_nr]->edfhdr->edfparam[signalcomp[signal_nr]->edfsignal[0]].bitvalue / (signalcomp[signal_nr]->sensitivity[0] * mainwindow->pixelsizefactor); signalcomp[signal_nr]->screen_offset = ((signalcomp[signal_nr]->max_dig_value + signalcomp[signal_nr]->min_dig_value) / 2.0) * signalcomp[signal_nr]->sensitivity[0]; } drawCurve_stage_1(); sidemenu->close(); } void ViewCurve::ColorButton() { int color; sidemenu->hide(); UI_ColorMenuDialog colormenudialog(&color, this); if(color < 0) { sidemenu->close(); return; } mainwindow->signalcomp[signal_nr]->color = color; update(); sidemenu->close(); } void ViewCurve::ScaleBox2Changed(double value) { mainwindow->signalcomp[signal_nr]->screen_offset = -(value / (mainwindow->pixelsizefactor * mainwindow->signalcomp[signal_nr]->voltpercm)); drawCurve_stage_1(); } void ViewCurve::ScaleBoxChanged(double value) { int i; double original_value; if(mainwindow->signalcomp[signal_nr]->edfhdr->edfparam[mainwindow->signalcomp[signal_nr]->edfsignal[0]].bitvalue < 0.0) { value *= -1.0; } for(i=0; isignalcomp[signal_nr]->num_of_signals; i++) { mainwindow->signalcomp[signal_nr]->sensitivity[i] = mainwindow->signalcomp[signal_nr]->edfhdr->edfparam[mainwindow->signalcomp[signal_nr]->edfsignal[i]].bitvalue / value / mainwindow->pixelsizefactor; } original_value = mainwindow->signalcomp[signal_nr]->voltpercm; mainwindow->signalcomp[signal_nr]->voltpercm = value; mainwindow->signalcomp[signal_nr]->screen_offset *= (original_value / value); drawCurve_stage_1(); } void ViewCurve::RemovefilterButton() { int j; if(!mainwindow->signalcomps) { sidemenu->close(); return; } if(signal_nr>(mainwindow->signalcomps - 1)) { sidemenu->close(); return; } for(j=0; jsignalcomp[signal_nr]->filter_cnt; j++) { free(mainwindow->signalcomp[signal_nr]->filter[j]); } mainwindow->signalcomp[signal_nr]->filter_cnt = 0; for(j=0; jsignalcomp[signal_nr]->ravg_filter_cnt; j++) { free_ravg_filter(mainwindow->signalcomp[signal_nr]->ravg_filter[j]); } mainwindow->signalcomp[signal_nr]->ravg_filter_cnt = 0; if(mainwindow->signalcomp[signal_nr]->ecg_filter != NULL) { free_ecg_filter(mainwindow->signalcomp[signal_nr]->ecg_filter); mainwindow->signalcomp[signal_nr]->ecg_filter = NULL; strcpy(mainwindow->signalcomp[signal_nr]->signallabel, mainwindow->signalcomp[signal_nr]->signallabel_bu); mainwindow->signalcomp[signal_nr]->signallabellen = mainwindow->signalcomp[signal_nr]->signallabellen_bu; strcpy(mainwindow->signalcomp[signal_nr]->physdimension, mainwindow->signalcomp[signal_nr]->physdimension_bu); } if(mainwindow->signalcomp[signal_nr]->zratio_filter != NULL) { free_zratio_filter(mainwindow->signalcomp[signal_nr]->zratio_filter); mainwindow->signalcomp[signal_nr]->zratio_filter = NULL; strcpy(mainwindow->signalcomp[signal_nr]->signallabel, mainwindow->signalcomp[signal_nr]->signallabel_bu); mainwindow->signalcomp[signal_nr]->signallabellen = mainwindow->signalcomp[signal_nr]->signallabellen_bu; strcpy(mainwindow->signalcomp[signal_nr]->physdimension, mainwindow->signalcomp[signal_nr]->physdimension_bu); } for(j=0; jsignalcomp[signal_nr]->fidfilter_cnt; j++) { free(mainwindow->signalcomp[signal_nr]->fidfilter[j]); fid_run_free(mainwindow->signalcomp[signal_nr]->fid_run[j]); fid_run_freebuf(mainwindow->signalcomp[signal_nr]->fidbuf[j]); fid_run_freebuf(mainwindow->signalcomp[signal_nr]->fidbuf2[j]); } mainwindow->signalcomp[signal_nr]->fidfilter_cnt = 0; mainwindow->signalcomp[signal_nr]->signallabel[mainwindow->signalcomp[signal_nr]->signallabellen] = 0; drawCurve_stage_1(); sidemenu->close(); } void ViewCurve::RemovesignalButton() { int i, j, p; if(!mainwindow->signalcomps) { sidemenu->close(); return; } if(signal_nr>(mainwindow->signalcomps - 1)) { sidemenu->close(); return; } if(mainwindow->spectrumdock->signalcomp == mainwindow->signalcomp[signal_nr]) { mainwindow->spectrumdock->clear(); mainwindow->spectrumdock->dock->hide(); } for(i=0; isignalcomp[signal_nr]->spectr_dialog[i]; if(p != 0) { delete mainwindow->spectrumdialog[p - 1]; mainwindow->spectrumdialog[p - 1] = NULL; } } for(i=0; isignalcomp[signal_nr]->avg_dialog[i]; if(p != 0) { delete mainwindow->averagecurvedialog[p - 1]; mainwindow->averagecurvedialog[p - 1] = NULL; } } for(i=0; isignalcomp[signal_nr]->zscoredialog[i]; if(p != 0) { delete mainwindow->zscoredialog[p - 1]; mainwindow->zscoredialog[p - 1] = NULL; } } if(mainwindow->signalcomp[signal_nr]->hascursor2) { crosshair_2.active = 0; crosshair_2.moving = 0; } if(mainwindow->signalcomp[signal_nr]->hascursor1) { crosshair_1.active = 0; crosshair_2.active = 0; crosshair_1.moving = 0; crosshair_2.moving = 0; for(i=0; isignalcomps; i++) { mainwindow->signalcomp[i]->hascursor2 = 0; } } if(mainwindow->signalcomp[signal_nr]->hasruler) { ruler_active = 0; ruler_moving = 0; } for(j=0; jsignalcomp[signal_nr]->filter_cnt; j++) { free(mainwindow->signalcomp[signal_nr]->filter[j]); } mainwindow->signalcomp[signal_nr]->filter_cnt = 0; for(j=0; jsignalcomp[signal_nr]->ravg_filter_cnt; j++) { free_ravg_filter(mainwindow->signalcomp[signal_nr]->ravg_filter[j]); } mainwindow->signalcomp[signal_nr]->ravg_filter_cnt = 0; if(mainwindow->signalcomp[signal_nr]->ecg_filter != NULL) { free_ecg_filter(mainwindow->signalcomp[signal_nr]->ecg_filter); mainwindow->signalcomp[signal_nr]->ecg_filter = NULL; strcpy(mainwindow->signalcomp[signal_nr]->signallabel, mainwindow->signalcomp[signal_nr]->signallabel_bu); mainwindow->signalcomp[signal_nr]->signallabellen = mainwindow->signalcomp[signal_nr]->signallabellen_bu; strcpy(mainwindow->signalcomp[signal_nr]->physdimension, mainwindow->signalcomp[signal_nr]->physdimension_bu); } if(mainwindow->signalcomp[signal_nr]->zratio_filter != NULL) { free_zratio_filter(mainwindow->signalcomp[signal_nr]->zratio_filter); mainwindow->signalcomp[signal_nr]->zratio_filter = NULL; strcpy(mainwindow->signalcomp[signal_nr]->signallabel, mainwindow->signalcomp[signal_nr]->signallabel_bu); mainwindow->signalcomp[signal_nr]->signallabellen = mainwindow->signalcomp[signal_nr]->signallabellen_bu; strcpy(mainwindow->signalcomp[signal_nr]->physdimension, mainwindow->signalcomp[signal_nr]->physdimension_bu); } for(j=0; jsignalcomp[signal_nr]->fidfilter_cnt; j++) { free(mainwindow->signalcomp[signal_nr]->fidfilter[j]); fid_run_free(mainwindow->signalcomp[signal_nr]->fid_run[j]); fid_run_freebuf(mainwindow->signalcomp[signal_nr]->fidbuf[j]); fid_run_freebuf(mainwindow->signalcomp[signal_nr]->fidbuf2[j]); } mainwindow->signalcomp[signal_nr]->fidfilter_cnt = 0; free(mainwindow->signalcomp[signal_nr]); for(i=signal_nr; isignalcomps - 1; i++) { mainwindow->signalcomp[i] = mainwindow->signalcomp[i + 1]; } mainwindow->signalcomps--; drawCurve_stage_1(); sidemenu->close(); } void ViewCurve::RulerButton() { int i; crosshair_1.moving = 0; crosshair_2.moving = 0; ruler_active = 0; ruler_moving = 0; use_move_events = 0; setMouseTracking(FALSE); for(i=0; isignalcomps; i++) { mainwindow->signalcomp[i]->hasruler = 0; } if(width() < 300) { goto END_OF_FUNC; } if(height() < 300) { goto END_OF_FUNC; } if((mainwindow->pagetime / TIME_DIMENSION) < 2LL) { QMessageBox messagewindow(QMessageBox::Warning, "Ruler", "The ruler can not be used when the Timescale\n is set to a value less than 2 seconds."); messagewindow.exec(); goto END_OF_FUNC; } if((mainwindow->pagetime / TIME_DIMENSION) > 120LL) { QMessageBox messagewindow(QMessageBox::Warning, "Ruler", "The ruler can not be used when the Timescale\n is set to a value more than 120 seconds."); messagewindow.exec(); goto END_OF_FUNC; } if((mainwindow->signalcomp[signal_nr]->voltpercm < 1.0) && (mainwindow->signalcomp[signal_nr]->voltpercm > -1.0)) { QMessageBox messagewindow(QMessageBox::Warning, "Ruler", "The ruler can not be used when the Amplitude\n is set to a value less than 1."); messagewindow.exec(); goto END_OF_FUNC; } if((mainwindow->signalcomp[signal_nr]->voltpercm > 2000.0) || (mainwindow->signalcomp[signal_nr]->voltpercm < -2000.0)) { QMessageBox messagewindow(QMessageBox::Warning, "Ruler", "The ruler can not be used when the Amplitude\n is set to a value more than 2000."); messagewindow.exec(); goto END_OF_FUNC; } ruler_x_position = 200; ruler_y_position = 200; mainwindow->signalcomp[signal_nr]->hasruler = 1; ruler_active = 1; update(); END_OF_FUNC: sidemenu->close(); } void ViewCurve::CrosshairButton() { int i; if(!crosshair_1.active) { for(i=0; isignalcomps; i++) { mainwindow->signalcomp[i]->hascursor1 = 0; mainwindow->signalcomp[i]->hascursor2 = 0; } crosshair_1.value = 0.0; crosshair_2.value = 0.0; mainwindow->signalcomp[signal_nr]->hascursor1 = 1; use_move_events = 0; setMouseTracking(TRUE); crosshair_1.active = 1; crosshair_2.active = 0; crosshair_1.moving = 0; crosshair_2.moving = 0; crosshair_1.file_num = mainwindow->signalcomp[signal_nr]->filenum; crosshair_1.x_position = w * 0.3; crosshair_1.y_position = h * 0.7; drawCurve_stage_1(); } else { if(!crosshair_2.active) { for(i=0; isignalcomps; i++) { mainwindow->signalcomp[i]->hascursor2 = 0; } crosshair_2.value = 0.0; mainwindow->signalcomp[signal_nr]->hascursor2 = 1; use_move_events = 0; setMouseTracking(TRUE); crosshair_2.active = 1; crosshair_1.moving = 0; crosshair_2.moving = 0; crosshair_2.file_num = mainwindow->signalcomp[signal_nr]->filenum; crosshair_2.x_position = w * 0.3; crosshair_2.y_position = h * 0.7; drawCurve_stage_1(); } } sidemenu->close(); } void ViewCurve::resizeEvent(QResizeEvent *rs_event) { drawCurve_stage_1(); QWidget::resizeEvent(rs_event); } inline void ViewCurve::floating_ruler(QPainter *painter, int x_pos, int y_pos, struct signalcompblock *signalcomp, int print_linewidth) { int i, j; double d_tmp, d_tmp2, h_size, w_size, pixels_per_second; char str_hz[7][16]={" 9", "10", "11", "12", "13", "14", "15"}; char str_uv[5][16]={"200", "150", "100", "50", "0"}; char str_s[4][16]={"1.00", "0.75", "0.50", "0.25"}; if(w < 400) { return; } if((mainwindow->pagetime / TIME_DIMENSION) < 2LL) { return; } if((mainwindow->pagetime / TIME_DIMENSION) > 60LL) { return; } if((signalcomp->voltpercm < 1.0) && (signalcomp->voltpercm > -1.0)) { return; } if((signalcomp->voltpercm > 2000.0) || (signalcomp->voltpercm < -2000.0)) { return; } x_pos *= printsize_x_factor; y_pos *= printsize_y_factor; pixels_per_second = ((double)w) / (((double)mainwindow->pagetime) / ((double)TIME_DIMENSION)); h_size = 4.0 * painter_pixelsizefactor; w_size = (double)w / 10.0; d_tmp = h_size / 7.0; d_tmp2 = h_size / 14.0; if(floating_ruler_value) { for(i=0; i<7; i++) { snprintf(str_hz[i], 15, "%.1f", (pixels_per_second / w_size) * (2.0 + i)); str_hz[i][15] = 0; } if(((int)signalcomp->voltpercm) < 20) { for(i=0; i<5; i++) { snprintf(str_uv[i], 15, "%.1f", signalcomp->voltpercm * i * (double)(signalcomp->polarity * -1)); str_uv[i][15] = 0; } } else { for(i=0; i<5; i++) { snprintf(str_uv[i], 15, "%i", (int)(signalcomp->voltpercm * i * (double)(signalcomp->polarity * -1))); str_uv[i][15] = 0; } } } else { for(i=0; i<7; i++) { snprintf(str_hz[i], 15, "%.1f", (w_size / pixels_per_second) * (9.0 + i)); str_hz[i][15] = 0; } if(((int)signalcomp->voltpercm) < 20) { for(i=0; i<5; i++) { snprintf(str_uv[i], 15, "%.1f", signalcomp->voltpercm * (4 - i) * (double)signalcomp->polarity); str_uv[i][15] = 0; } } else { for(i=0; i<5; i++) { snprintf(str_uv[i], 15, "%i", (int)(signalcomp->voltpercm * (4 - i)) * signalcomp->polarity); str_uv[i][15] = 0; } } } for(i=0; i<4; i++) { snprintf(str_s[i], 15, "%.2f", ((w / 40.0) / pixels_per_second) * (4 - i)); str_s[i][15] = 0; } painter->setPen((Qt::GlobalColor)floating_ruler_color); painter->drawText(x_pos, y_pos - ((double)h / 80.0), "Hz"); for(i=0; i<7; i++) { painter->drawText(x_pos - ((double)w / 30.0), y_pos + ((double)h / 204.8) + d_tmp2 + (d_tmp * i), str_hz[i]); } for(i=1; i<7; i++) { painter->drawLine(x_pos, y_pos + (d_tmp * i), x_pos + w_size, y_pos + (d_tmp * i)); } painter->drawRect(x_pos, y_pos, w_size, h_size); if(floating_ruler_value) { for(j=2; j<9; j++) { d_tmp2 = w_size / j; for(i=1; idrawLine(x_pos + (d_tmp2 * i), y_pos + (d_tmp * (j - 2)), x_pos + (d_tmp2 * i), y_pos + (d_tmp * (j - 1))); } } } else { for(j=9; j<16; j++) { d_tmp2 = w_size / j; for(i=1; idrawLine(x_pos + (d_tmp2 * i), y_pos + (d_tmp * (j - 9)), x_pos + (d_tmp2 * i), y_pos + (d_tmp * (j - 8))); } } } painter->drawText(x_pos + (3.0 * printsize_x_factor), y_pos + h_size + (25.0 * printsize_y_factor), "more..."); x_pos += (w_size + ((double)w / 18.0)); d_tmp = h_size / 4.0; painter->drawText(x_pos - ((double)w / 45.0), y_pos - ((double)h / 80.0), signalcomp->physdimension); for(i=0; i<5; i++) { painter->drawText(x_pos - ((double)w / 45.0), y_pos + ((double)h / 204.8) + (d_tmp * i), str_uv[i]); painter->drawLine(x_pos + ((double)w / 160.0), y_pos + (d_tmp * i), x_pos + ((double)w / 45.7), y_pos + (d_tmp * i)); } painter->drawLine(x_pos + ((double)w / 45.7), y_pos, x_pos + ((double)w / 45.7), y_pos + h_size); d_tmp = h_size / 20.0; for(i=1; i<20; i++) { painter->drawLine(x_pos + ((double)w / 71.1), y_pos + (d_tmp * i), x_pos + ((double)w / 45.7), y_pos + (d_tmp * i)); } x_pos += ((double)w / 10.0); painter->drawLine(x_pos, y_pos, x_pos + (w_size / 2.0), y_pos + h_size); painter->drawLine(x_pos + w_size, y_pos, x_pos + (w_size / 2.0), y_pos + h_size); d_tmp = h_size / 4.0; d_tmp2 = w_size / 8.0; for(i=0; i<4; i++) { painter->drawLine(x_pos + (d_tmp2 * i), y_pos + (d_tmp * i), x_pos + w_size - (d_tmp2 * i), y_pos + (d_tmp * i)); } for(i=0; i<4; i++) { painter->drawText(x_pos - ((double)w / 25.0) + (d_tmp2 * i), y_pos + ((double)h / 204.8) + (d_tmp * i), str_s[i]); } painter->drawText(x_pos + ((double)w / 125.0) + w_size, y_pos + ((double)h / 204.8), "Sec"); special_pen->setColor((Qt::GlobalColor)floating_ruler_color); special_pen->setWidth(print_linewidth); painter->setPen(*special_pen); d_tmp = h_size / 20.0; d_tmp2 = w_size / 40.0; for(i=1; i<20; i++) { painter->drawLine(x_pos + (d_tmp2 * i), y_pos + (d_tmp * i), x_pos + w_size - (d_tmp2 * i), y_pos + (d_tmp * i)); } } void ViewCurve::backup_colors_for_printing() { int i; backup_color_1 = backgroundcolor; backgroundcolor = Qt::white; backup_color_2 = small_ruler_color; small_ruler_color = Qt::black; backup_color_3 = big_ruler_color; big_ruler_color = Qt::black; backup_color_4 = mouse_rect_color; mouse_rect_color = Qt::black; backup_color_5 = text_color; text_color = Qt::black; backup_color_14 = floating_ruler_color; floating_ruler_color = Qt::black; for(i=0; isignalcomps; i++) { backup_color_10[i] = mainwindow->signalcomp[i]->color; mainwindow->signalcomp[i]->color = Qt::black; } backup_color_11 = crosshair_1.color; crosshair_1.color = Qt::black; backup_color_12 = crosshair_2.color; crosshair_2.color = Qt::black; backup_color_13 = baseline_color; baseline_color = Qt::black; backup_color_15 = annot_marker_color; annot_marker_color = Qt::black; } void ViewCurve::restore_colors_after_printing() { int i; backgroundcolor = backup_color_1; small_ruler_color = backup_color_2; big_ruler_color = backup_color_3; mouse_rect_color = backup_color_4; text_color = backup_color_5; floating_ruler_color = backup_color_14; for(i=0; isignalcomps; i++) { mainwindow->signalcomp[i]->color = backup_color_10[i]; } crosshair_1.color = backup_color_11; crosshair_2.color = backup_color_12; baseline_color = backup_color_13; annot_marker_color = backup_color_15; } void ViewCurve::setCrosshair_1_center(void) { crosshair_1.x_position = width() / 2; } void ViewCurve::strip_types_from_label(char *label) { int i, len; len = strlen(label); if(len<16) { return; } if((!(strncmp(label, "EEG ", 4))) ||(!(strncmp(label, "ECG ", 4))) ||(!(strncmp(label, "EOG ", 4))) ||(!(strncmp(label, "ERG ", 4))) ||(!(strncmp(label, "EMG ", 4))) ||(!(strncmp(label, "MEG ", 4))) ||(!(strncmp(label, "MCG ", 4)))) { if(label[4]!=' ') { for(i=0; i<(len-4); i++) { label[i] = label[i+4]; } for(; isetMinimumSize(800, 500); SignalsDialog->setMaximumSize(800, 500); SignalsDialog->setWindowTitle("Signals"); SignalsDialog->setModal(TRUE); SignalsDialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); filelist = new QListWidget(SignalsDialog); filelist->setGeometry(10, 10, 780, 75); for(i=0; ifiles_open; i++) { new QListWidgetItem(QString::fromLocal8Bit(mainwindow->edfheaderlist[i]->filename), filelist); } label1 = new QLabel(SignalsDialog); label1->setGeometry(10, 95, 760, 20); label2 = new QLabel(SignalsDialog); label2->setGeometry(10, 120, 760, 20); label3 = new QLabel(SignalsDialog); label3->setGeometry(10, 145, 250, 20); label4 = new QLabel(SignalsDialog); label4->setGeometry(270, 145, 250, 20); label5 = new QLabel(SignalsDialog); label5->setGeometry(10, 190, 120, 20); label5->setText("Signals in file"); label6 = new QLabel(SignalsDialog); label6->setGeometry(430, 190, 120, 20); label6->setText("Signal Composition"); colorlabel = new QLabel(SignalsDialog); colorlabel->setGeometry(320, 380, 100, 20); colorlabel->setText(" Color"); signallist = new QListWidget(SignalsDialog); signallist->setGeometry(10, 210, 300, 225); signallist->setFont(*mainwindow->monofont); signallist->setSelectionBehavior(QAbstractItemView::SelectRows); signallist->setSelectionMode(QAbstractItemView::ExtendedSelection); CloseButton = new QPushButton(SignalsDialog); CloseButton->setGeometry(690, 455, 100, 25); CloseButton->setText("&Close"); SelectAllButton = new QPushButton(SignalsDialog); SelectAllButton->setGeometry(10, 455, 100, 25); SelectAllButton->setText("&Select All"); HelpButton = new QPushButton(SignalsDialog); HelpButton->setGeometry(690, 120, 100, 25); HelpButton->setText("&Help"); DisplayButton = new QPushButton(SignalsDialog); DisplayButton->setGeometry(150, 455, 160, 25); DisplayButton->setText("&Add signal(s)"); DisplayCompButton = new QPushButton(SignalsDialog); DisplayCompButton->setGeometry(430, 455, 160, 25); DisplayCompButton->setText("&Make derivation"); AddButton = new QPushButton(SignalsDialog); AddButton->setGeometry(320, 250, 100, 25); AddButton->setText("Add->"); SubtractButton = new QPushButton(SignalsDialog); SubtractButton->setGeometry(320, 285, 100, 25); SubtractButton->setText("Subtract->"); RemoveButton = new QPushButton(SignalsDialog); RemoveButton->setGeometry(320, 320, 100, 25); RemoveButton->setText("Remove<-"); ColorButton = new SpecialButton(SignalsDialog); ColorButton->setGeometry(320, 405, 100, 25); ColorButton->setColor((Qt::GlobalColor)mainwindow->maincurve->signal_color); compositionlist = new QListWidget(SignalsDialog); compositionlist->setGeometry(430, 210, 360, 225); compositionlist->setFont(*mainwindow->monofont); compositionlist->setSelectionBehavior(QAbstractItemView::SelectRows); compositionlist->setSelectionMode(QAbstractItemView::ExtendedSelection); smp_per_record = 0; QObject::connect(CloseButton, SIGNAL(clicked()), SignalsDialog, SLOT(close())); QObject::connect(SelectAllButton, SIGNAL(clicked()), this, SLOT(SelectAllButtonClicked())); QObject::connect(HelpButton, SIGNAL(clicked()), this, SLOT(HelpButtonClicked())); QObject::connect(DisplayButton, SIGNAL(clicked()), this, SLOT(DisplayButtonClicked())); QObject::connect(DisplayCompButton, SIGNAL(clicked()), this, SLOT(DisplayCompButtonClicked())); QObject::connect(AddButton, SIGNAL(clicked()), this, SLOT(AddButtonClicked())); QObject::connect(SubtractButton, SIGNAL(clicked()), this, SLOT(SubtractButtonClicked())); QObject::connect(RemoveButton, SIGNAL(clicked()), this, SLOT(RemoveButtonClicked())); QObject::connect(ColorButton, SIGNAL(clicked(SpecialButton *)), this, SLOT(ColorButtonClicked(SpecialButton *))); QObject::connect(filelist, SIGNAL(currentRowChanged(int)), this, SLOT(show_signals(int))); curve_color = mainwindow->maincurve->signal_color; filelist->setCurrentRow(mainwindow->files_open - 1); signallist->setFocus(); SignalsDialog->exec(); } void UI_Signalswindow::ColorButtonClicked(SpecialButton *) { int color; UI_ColorMenuDialog colormenudialog(&color); if(color < 0) return; ColorButton->setColor((Qt::GlobalColor)color); curve_color = color; } void UI_Signalswindow::DisplayCompButtonClicked() { int i, j, n; char str[512], str2[128]; struct signalcompblock *newsignalcomp; QListWidgetItem *item; n = compositionlist->count(); if(!n) { return; } newsignalcomp = (struct signalcompblock *)calloc(1, sizeof(struct signalcompblock)); if(newsignalcomp==NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Internal error: Memory allocation error:\n\"new signal composition\""); messagewindow.exec(); SignalsDialog->close(); return; } newsignalcomp->num_of_signals = n; newsignalcomp->filenum = filelist->currentRow(); newsignalcomp->edfhdr = mainwindow->edfheaderlist[newsignalcomp->filenum]; newsignalcomp->file_duration = newsignalcomp->edfhdr->long_data_record_duration * newsignalcomp->edfhdr->datarecords; newsignalcomp->voltpercm = 100.0; newsignalcomp->color = curve_color; newsignalcomp->hasruler = 0; newsignalcomp->polarity = 1; for(i=0; iitem(i)->text().toLatin1().data()); for(j=0; jedfhdr->edfsignals; j++) { if(!strncmp(newsignalcomp->edfhdr->edfparam[j].label, str + 5, 16)) { if(j != compositionlist->item(i)->data(Qt::UserRole).toInt()) continue; newsignalcomp->edfsignal[i] = j; newsignalcomp->factor[i] = str[23] - 48; if(str[3]=='-') { newsignalcomp->factor[i] = -(newsignalcomp->factor[i]); strcat(newsignalcomp->signallabel, "- "); } else { if(i) { strcat(newsignalcomp->signallabel, "+ "); } } strcpy(str2, newsignalcomp->edfhdr->edfparam[j].label); strip_types_from_label(str2); strcat(newsignalcomp->signallabel, str2); remove_trailing_spaces(newsignalcomp->signallabel); strcat(newsignalcomp->signallabel, " "); if(newsignalcomp->edfhdr->edfparam[j].bitvalue < 0.0) { newsignalcomp->voltpercm = -100.0; } newsignalcomp->sensitivity[i] = newsignalcomp->edfhdr->edfparam[j].bitvalue / ((double)newsignalcomp->voltpercm * mainwindow->pixelsizefactor); } } } remove_trailing_spaces(newsignalcomp->signallabel); newsignalcomp->signallabellen = strlen(newsignalcomp->signallabel); strcpy(newsignalcomp->physdimension, newsignalcomp->edfhdr->edfparam[newsignalcomp->edfsignal[0]].physdimension); remove_trailing_spaces(newsignalcomp->physdimension); mainwindow->signalcomp[mainwindow->signalcomps] = newsignalcomp; mainwindow->signalcomps++; while(compositionlist->count()) { item = compositionlist->takeItem(0); delete item; } mainwindow->setup_viewbuf(); smp_per_record = 0; } void UI_Signalswindow::DisplayButtonClicked() { int i, n, s; struct signalcompblock *newsignalcomp; QListWidgetItem *item; QList selectedlist; selectedlist = signallist->selectedItems(); n = selectedlist.size(); if(!n) { SignalsDialog->close(); return; } for(i=0; iclose(); return; } newsignalcomp->num_of_signals = 1; newsignalcomp->filenum = filelist->currentRow(); newsignalcomp->edfhdr = mainwindow->edfheaderlist[newsignalcomp->filenum]; newsignalcomp->file_duration = newsignalcomp->edfhdr->long_data_record_duration * newsignalcomp->edfhdr->datarecords; newsignalcomp->voltpercm = 100.0; newsignalcomp->color = curve_color; newsignalcomp->hasruler = 0; newsignalcomp->polarity = 1; item = selectedlist.at(i); s = item->data(Qt::UserRole).toInt(); newsignalcomp->edfsignal[0] = s; newsignalcomp->factor[0] = 1; if(newsignalcomp->edfhdr->edfparam[s].bitvalue < 0.0) { newsignalcomp->voltpercm = -100.0; } newsignalcomp->sensitivity[0] = newsignalcomp->edfhdr->edfparam[s].bitvalue / ((double)newsignalcomp->voltpercm * mainwindow->pixelsizefactor); strcpy(newsignalcomp->signallabel, newsignalcomp->edfhdr->edfparam[s].label); strip_types_from_label(newsignalcomp->signallabel); remove_trailing_spaces(newsignalcomp->signallabel); newsignalcomp->file_duration = newsignalcomp->edfhdr->long_data_record_duration * newsignalcomp->edfhdr->datarecords; newsignalcomp->signallabellen = strlen(newsignalcomp->signallabel); strcpy(newsignalcomp->physdimension, newsignalcomp->edfhdr->edfparam[s].physdimension); remove_trailing_spaces(newsignalcomp->physdimension); mainwindow->signalcomp[mainwindow->signalcomps] = newsignalcomp; mainwindow->signalcomps++; } SignalsDialog->close(); mainwindow->setup_viewbuf(); } void UI_Signalswindow::RemoveButtonClicked() { int i, n, row; QListWidgetItem *item; QList selectedlist; selectedlist = compositionlist->selectedItems(); n = selectedlist.size(); if(!n) return; for(i=0; irow(item); item = compositionlist->takeItem(row); delete item; } } void UI_Signalswindow::AddButtonClicked() { int i, j, k, n, s, row, duplicate; char str[256]; QListWidgetItem *item; QList selectedlist; selectedlist = signallist->selectedItems(); n = selectedlist.size(); if(!n) return; if(!compositionlist->count()) { smp_per_record = 0; physdimension[0] = 0; bitvalue = 0.0; } for(i=0; idata(Qt::UserRole).toInt(); row = filelist->currentRow(); if(smp_per_record) { if(smp_per_record!=mainwindow->edfheaderlist[row]->edfparam[s].smp_per_record) { QMessageBox messagewindow(QMessageBox::Warning, "Warning", "It is only possible to make combinations/derivations with signals which:\n" " - are from the same file\n" " - have the same samplerate\n" " - have the same physical dimension (e.g. uV)\n" " - have the same sensitivity (e.g. uV/bit)"); messagewindow.exec(); continue; } } else { smp_per_record = mainwindow->edfheaderlist[row]->edfparam[s].smp_per_record; } if(physdimension[0]) { if(strcmp(physdimension, mainwindow->edfheaderlist[row]->edfparam[s].physdimension)) { QMessageBox messagewindow(QMessageBox::Warning, "Warning", "It is only possible to make combinations/derivations with signals which:\n" " - are from the same file\n" " - have the same samplerate\n" " - have the same physical dimension (e.g. uV)\n" " - have the same sensitivity (e.g. uV/bit)"); messagewindow.exec(); continue; } } else { strcpy(physdimension, mainwindow->edfheaderlist[row]->edfparam[s].physdimension); } if(bitvalue!=0.0) { if(bitvalue!=mainwindow->edfheaderlist[row]->edfparam[s].bitvalue) { QMessageBox messagewindow(QMessageBox::Warning, "Warning", "It is only possible to make combinations/derivations with signals which:\n" " - are from the same file\n" " - have the same samplerate\n" " - have the same physical dimension (e.g. uV)\n" " - have the same sensitivity (e.g. uV/bit)"); messagewindow.exec(); continue; } } else { bitvalue = mainwindow->edfheaderlist[row]->edfparam[s].bitvalue; } duplicate = 0; k = compositionlist->count(); for(j=0; jitem(j); strcpy(str, item->text().toLatin1().data()); if(!strncmp(mainwindow->edfheaderlist[row]->edfparam[s].label, str + 5, 16)) { if(str[3]=='+') { if(s == item->data(Qt::UserRole).toInt()) { duplicate = 1; break; } } } } if(duplicate) { if(str[23]==57) continue; str[23] += 1; item->setText(str); } else { snprintf(str, 200, "%-2i + ", row + 1); strcat(str, mainwindow->edfheaderlist[row]->edfparam[s].label); strcat(str, " x1"); snprintf(str + strlen(str), 50, " %5.fHz", mainwindow->edfheaderlist[row]->edfparam[s].smp_per_record / mainwindow->edfheaderlist[row]->data_record_duration); item = new QListWidgetItem; item->setData(Qt::UserRole, QVariant(s)); item->setText(str); compositionlist->addItem(item); } } } void UI_Signalswindow::SubtractButtonClicked() { int i, j, k, n, s, row, duplicate; char str[256]; QListWidgetItem *item; QList selectedlist; selectedlist = signallist->selectedItems(); n = selectedlist.size(); if(!n) return; if(!compositionlist->count()) { smp_per_record = 0; physdimension[0] = 0; bitvalue = 0.0; } for(i=0; idata(Qt::UserRole).toInt(); row = filelist->currentRow(); if(smp_per_record) { if(smp_per_record!=mainwindow->edfheaderlist[row]->edfparam[s].smp_per_record) { QMessageBox messagewindow(QMessageBox::Warning, "Warning", "It is only possible to make combinations/derivations with signals which:\n" " - are from the same file\n" " - have the same samplerate\n" " - have the same physical dimension (e.g. uV)\n" " - have the same sensitivity (e.g. uV/bit)"); messagewindow.exec(); continue; } } else { smp_per_record = mainwindow->edfheaderlist[row]->edfparam[s].smp_per_record; } if(physdimension[0]) { if(strcmp(physdimension, mainwindow->edfheaderlist[row]->edfparam[s].physdimension)) { QMessageBox messagewindow(QMessageBox::Warning, "Warning", "It is only possible to make combinations/derivations with signals which:\n" " - are from the same file\n" " - have the same samplerate\n" " - have the same physical dimension (e.g. uV)\n" " - have the same sensitivity (e.g. uV/bit)"); messagewindow.exec(); continue; } } else { strcpy(physdimension, mainwindow->edfheaderlist[row]->edfparam[s].physdimension); } if(bitvalue!=0.0) { if(bitvalue!=mainwindow->edfheaderlist[row]->edfparam[s].bitvalue) { QMessageBox messagewindow(QMessageBox::Warning, "Warning", "It is only possible to make combinations/derivations with signals which:\n" " - are from the same file\n" " - have the same samplerate\n" " - have the same physical dimension (e.g. uV)\n" " - have the same sensitivity (e.g. uV/bit)"); messagewindow.exec(); continue; } } else { bitvalue = mainwindow->edfheaderlist[row]->edfparam[s].bitvalue; } duplicate = 0; k = compositionlist->count(); for(j=0; jitem(j); strcpy(str, item->text().toLatin1().data()); if(!strncmp(mainwindow->edfheaderlist[row]->edfparam[s].label, str + 5, 16)) { if(str[3]=='-') { duplicate = 1; break; } } } if(duplicate) { if(str[23]==57) continue; str[23] += 1; item->setText(str); } else { snprintf(str, 200, "%-2i - ", row + 1); strcat(str, mainwindow->edfheaderlist[row]->edfparam[s].label); strcat(str, " x1"); snprintf(str + strlen(str), 50, " %5.fHz", mainwindow->edfheaderlist[row]->edfparam[s].smp_per_record / mainwindow->edfheaderlist[row]->data_record_duration); item = new QListWidgetItem; item->setData(Qt::UserRole, QVariant(s)); item->setText(str); compositionlist->addItem(item); } } } void UI_Signalswindow::show_signals(int row) { int i, j, len, skip, signal_cnt; char str[256]; long long file_duration; QListWidgetItem *item; struct date_time_struct date_time; if(row<0) return; while(signallist->count()) { delete signallist->item(0); } if((mainwindow->edfheaderlist[row]->edfplus)||(mainwindow->edfheaderlist[row]->bdfplus)) { strcpy(str, "Subject "); strcat(str, mainwindow->edfheaderlist[row]->plus_patient_name); strcat(str, " "); strcat(str, mainwindow->edfheaderlist[row]->plus_birthdate); strcat(str, " "); strcat(str, mainwindow->edfheaderlist[row]->plus_patientcode); label1->setText(str); strcpy(str, "Recording "); strcat(str, mainwindow->edfheaderlist[row]->plus_admincode); label2->setText(str); } else { strcpy(str, "Subject "); strcat(str, mainwindow->edfheaderlist[row]->patient); len = strlen(str); for(j=0; jsetText(str); strcpy(str, "Recording "); strcat(str, mainwindow->edfheaderlist[row]->recording); len = strlen(str); for(j=0; jsetText(str); } utc_to_date_time(mainwindow->edfheaderlist[row]->utc_starttime, &date_time); date_time.month_str[0] += 32; date_time.month_str[1] += 32; date_time.month_str[2] += 32; snprintf(str, 256, "Start %i %s %i %2i:%02i:%02i", date_time.day, date_time.month_str, date_time.year, date_time.hour, date_time.minute, date_time.second); label3->setText(str); strcpy(str, "Duration "); file_duration = mainwindow->edfheaderlist[row]->long_data_record_duration * mainwindow->edfheaderlist[row]->datarecords; snprintf(str + 11, 240, "%2i:%02i:%02i", (int)((file_duration / TIME_DIMENSION)/ 3600LL), (int)(((file_duration / TIME_DIMENSION) % 3600LL) / 60LL), (int)((file_duration / TIME_DIMENSION) % 60LL)); label4->setText(str); skip = 0; signal_cnt = mainwindow->edfheaderlist[row]->edfsignals; for(i=0; iedfheaderlist[row]->edfplus || mainwindow->edfheaderlist[row]->bdfplus) { for(j=0; jedfheaderlist[row]->nr_annot_chns; j++) { if(i==mainwindow->edfheaderlist[row]->annot_ch[j]) { skip = 1; break; } } if(skip) { skip = 0; continue; } } snprintf(str, 256, "%-3i ", i + 1); strcat(str, mainwindow->edfheaderlist[row]->edfparam[i].label); sprintf(str + strlen(str), " %f", mainwindow->edfheaderlist[row]->edfparam[i].smp_per_record / mainwindow->edfheaderlist[row]->data_record_duration); remove_trailing_zeros(str); strcat(str, " Hz"); item = new QListWidgetItem; item->setText(str); item->setData(Qt::UserRole, QVariant(i)); signallist->addItem(item); } SelectAllButtonClicked(); } void UI_Signalswindow::SelectAllButtonClicked() { int row, i; QListWidgetItem *item; row = signallist->count(); for(i=0; iitem(i); item->setSelected(TRUE); } } void UI_Signalswindow::HelpButtonClicked() { UI_Messagewindow popup_help("Help", "On top you will see a list of opened files.\n" "Select (highlight) the file from which you want to add signals. At the left part of the dialog you see a list of\n" "all the signals which are in the selected file. Select one or more signals and click on the \"Add signals\"\n" "button. Now you will see the selected signals on the screen.\n" "\nWhen you want to make a combination (derivation) of two or more signals, do as follows.\n" "Select the file from which you want to add signals. For example, we choose an EEG file which contains\n" "the signals \"P3\" and \"C3\" and we want to subtract \"C3\" from \"P3\".\n" "- Select (highlight) the signal \"P3\".\n" "- Click on the \"Add\" button.\n" "- Select (highlight) the signal \"C3\".\n" "- Click on the \"Subtract\" button.\n" "- Click on the \"Make derivation\" button.\n" "- The result of \"P3\" minus \"C3\" will appear on the screen."); } void UI_Signalswindow::strip_types_from_label(char *label) { int i, len; len = strlen(label); if(len<16) { return; } if((!(strncmp(label, "EEG ", 4))) ||(!(strncmp(label, "ECG ", 4))) ||(!(strncmp(label, "EOG ", 4))) ||(!(strncmp(label, "ERG ", 4))) ||(!(strncmp(label, "EMG ", 4))) ||(!(strncmp(label, "MEG ", 4))) ||(!(strncmp(label, "MCG ", 4)))) { if(label[4]!=' ') { for(i=0; i<(len-4); i++) { label[i] = label[i+4]; } for(; i #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "mainwindow.h" #include "colordialog.h" #include "special_button.h" #include "signalcurve.h" class UI_Mainwindow; class UI_OptionsDialog : public QObject { Q_OBJECT public: UI_OptionsDialog(QWidget *parent=0); UI_Mainwindow *mainwindow; private: QDialog *optionsdialog; QScrollArea *scrollarea; QFrame *frame; QGridLayout *scrolllayout; QTabWidget *tabholder; QWidget *tab1, *tab2, *tab3, *tab4; QVBoxLayout *mainLayout; QHBoxLayout *horLayout; QPushButton *CloseButton, *DefaultButton, *colorSchema_NK_Button, *colorSchema_Dark_Button, *ApplyButton, *DefaultButton2, *ApplyButton2, *saveColorSchemaButton, *loadColorSchemaButton; SpecialButton *BgColorButton, *SrColorButton, *BrColorButton, *MrColorButton, *TxtColorButton, *SigColorButton, *BaseColorButton, *Crh1ColorButton, *Crh2ColorButton, *FrColorButton, *AnnotMkrButton, *slabel2_1, *slabel2_3; QLabel *label1, *label2, *label3, *label4, *label5, *label6, *label7, *label8, *label9, *label10, *label11, *label12, *label13, *label4_1, *label4_2, *label4_3, *label4_4, *label4_5, *label4_6, *label4_7, *label4_8, *label4_9, *label4_10, *label2_2, *label2_4, *label1_3, *label2_3, *label3_3, *label3_4; QSpinBox *spinbox2_1, *spinbox2_2, *spinbox3_1, *spinbox4_1, *spinbox4_2, *spinbox4_3; QComboBox *combobox4_1, *combobox4_2, *combobox4_3; QCheckBox *checkbox1, *checkbox2, *checkbox3, *checkbox4, *checkbox4_1, *checkbox4_2, *checkbox4_3, *checkbox4_4, *checkbox4_5, *checkbox2_1; QTableWidget *colorBarTable; QRadioButton *radiobutton1, *radiobutton2, *radiobutton3; QLineEdit *lineEdit3_1; void update_interface(void); private slots: void BgColorButtonClicked(SpecialButton *); void SrColorButtonClicked(SpecialButton *); void BrColorButtonClicked(SpecialButton *); void MrColorButtonClicked(SpecialButton *); void TxtColorButtonClicked(SpecialButton *); void SigColorButtonClicked(SpecialButton *); void BaseColorButtonClicked(SpecialButton *); void Crh1ColorButtonClicked(SpecialButton *); void Crh2ColorButtonClicked(SpecialButton *); void FrColorButtonClicked(SpecialButton *); void AnnotMkrButtonClicked(SpecialButton *); void checkbox1Clicked(int); void checkbox2Clicked(int); void checkbox3Clicked(int); void checkbox4Clicked(int); void checkbox4_1Clicked(int); void checkbox4_2Clicked(int); void checkbox4_3Clicked(int); void checkbox4_4Clicked(int); void checkbox4_5Clicked(int); void DefaultButtonClicked(); void ApplyButtonClicked(); void colorBarButtonClicked(SpecialButton *); void DefaultButton2Clicked(); void checkBoxChanged(int); void ApplyButton2Clicked(); void radioButtonToggled(bool); void spinBoxValueChanged(double); void spinBox3_3ValueChanged(int); void labelEdited(const QString &); void calibrate_checkbox_stateChanged(int); void spinBox4_1ValueChanged(int); void combobox4_1IndexChanged(int); void combobox4_2IndexChanged(int); void combobox4_3IndexChanged(int); void spinBox4_2ValueChanged(int); void spinBox4_3ValueChanged(int); void saveColorSchemaButtonClicked(); void loadColorSchemaButtonClicked(); void loadColorSchema_NK(); void loadColorSchema_Dark(); }; #endif // OPTIONSFORM1_H edfbrowser_153_source/PaxHeaders.2978/doc0000644000175000001440000000013212251654530016637 xustar000000000000000030 mtime=1386699096.457032627 30 atime=1386699096.457032627 30 ctime=1386699096.457032627 edfbrowser_153_source/doc/0000755000175000001440000000000012251654530016445 5ustar00novarausers00000000000000edfbrowser_153_source/doc/PaxHeaders.2978/montage_file_format.txt0000644000175000001440000000013212251654530023456 xustar000000000000000030 mtime=1386699096.457032627 30 atime=1386699096.457032627 30 ctime=1386699096.457032627 edfbrowser_153_source/doc/montage_file_format.txt0000644000175000001440000003006512251654530023213 0ustar00novarausers00000000000000 This document describes the format used by EDFbrowser to write montage files. ----------------------------------------------------------------------------- The montage file uses only basic XML elements. XML attributes are not allowed. The first line of the file must contain: The root element must be "EDFbrowser_montage", like: Inside the root element "EDFbrowser_montage", there will be a child element for every signal composition. A signal composition represents one trace or curve on the screen. The name of this element must be "signalcomposition", like: Inside every element "signalcomposition", there must be one element with the name "num_of_signals", like: 2 The value of this element must be an integer within the range 1 to 512. (The example has a value of 2.) The value represents from how many signals it is derived i.e. if it's monopolar, bipolar or tripolar, etc. Note: all signals in the same signalcomposition must share the same samplerate and sensitivity. Inside every element "signalcomposition", there must be one element with the name "voltpercm", like: 100.000000 The value of this element must be a floating point number. (The example has a value of 100.0.) The value represents the amplitude of the signal expressed in it's physical dimension per cm (vertical). Inside every element "signalcomposition", there must be one element with the name "screen_offset", like: 0 The value of this element must be an integer or floating point number. (The example has a value of 0.) The value represents the vertical offset compared to the baseline. Inside every element "signalcomposition", there must be one element with the name "polarity", like: 1 The value of this element must be either 1 or -1. (The example has a value of 1.) The value has the following meanings: 1 : normal presentation (not inverted) -1 : signal will be drawn inverted (upside down) Inside every element "signalcomposition", there must be one element with the name "color", like: 2 The value of this element must be an integer within the range 2 to 18. (The example has a value of 2.) The value represents the color of the signalcomposition on the screen i.e. the trace or curve. Colortable: 2 Black 3 White 4 Dark gray 5 Gray 6 Light gray 7 Red 8 Green 9 Blue 10 Cyan 11 Magenta 12 Yellow 13 Dark red 14 Dark green 15 Dark blue 16 Dark cyan 17 Dark magenta 18 Dark Yellow Inside every element "signalcomposition", there can be one element with the name "alias", like: average An alias, if used, replaces the signalcomposition label on the screen. It does not influence the montages. Only 7-bit ASCII characters are allowed. Max 16 characters. Inside every element "signalcomposition", there can be one element with the name "fidfilter_cnt", like: 0 The value of this element must be an integer within the range 0 to 8. (The example has a value of 0.) The value represents the number of fid filters applied to the signalcomposition. Inside every element "signalcomposition", there can be one element with the name "ravg_filter_cnt", like: 0 The value of this element must be an integer within the range 0 to 8. (The example has a value of 0.) The value represents the number of running average filters applied to the signalcomposition. Inside every element "signalcomposition", there must be at least one element with the name "signal", like: The number of elements "signal" must be equal to the value of the element "num_of_signals". Note: all signals in the same signalcomposition must have the same samplerate and sensitivity. Inside every element "signal", there must be one element with the name "label", like: The value of this element must be a string containing only 7-bit ASCII characters. (The example has a value of "FP1".) The decimal value of every character must be in the range 32 to 126. This avoids the use of control-codes. The maximum amount of characters allowed is 16. There must be no termination character (like zero). The value represents the label of the signal in the file which must be used for this signalcomposition. Exception: Instead of an element "label", an element "edfindex" can be used: 4 The value of this element must be an integer within the range 0 to 511. (The example has a value of 4.) The value represents the number of the signal in the file which must be used for this signalcomposition. The first signal in an EDF-file has number 0, the second signal has number 1, the third signal has number 2, etc. Inside the element "signal", there must be one element with the name "factor", like: 1 The value of this element must be an integer in the range -128 to 128. 0 is not allowed. (The example has a value of 1.) The value of this element represents a multiplying factor. During the drawing of the samples of the respective signal on the screen, the values of the samples will be multiplied with this factor. If the value of element "fidfilter_cnt" is higher than zero, there must be at least one element with name "fidfilter", like: The number of elements "fidfilter" must be equal to the value of the element "fidfilter_cnt". Inside every element "fidfilter", there must be one element with the name "type", like: 0 The value of this element must be an integer in the range 0 to 4. (The example has a value of 0.) filtertype table: 0 higpass 1 lowpass 2 notch 3 bandpass 4 bandstop Note: when type = 2 (notch), element "model" must be 0 (Butterworth). Inside every element "fidfilter", there must be one element with the name "frequency", like: 0.5 The value of this element must be a floating point number. (The example has a value of 0.5 Hz.) The value represents the cut-off or notch frequency expressed in Hz. Inside every element "fidfilter", there must be one element with the name "frequency2", like: 100.0 The value of this element must be a floating point number. (The example has a value of 100.0 Hz.) The value represents the second cut-off frequency of a bandpass or bandstop filter expressed in Hz and must be higher than the value of "frequency". Inside every element "fidfilter", there must be one element with the name "ripple", like: 3.0 The value of this element must be a floating point number. (The example has a value of 3.0 dB.) The value represents the bandpass ripple expressed in dB. Inside every element "fidfilter", there must be one element with the name "order", like: 1 The value of this element must be an integer number within the range 1 to 100. (The example has a value of 1.) The value represents the filters order e.g. 1th order. Note: when type = 2 (notch), order must be in the range 3 to 100 and represents the Q-factor of the notch-filter. Inside every element "fidfilter", there must be one element with the name "model", like: 0 The value of this element must be an integer number within the range 0 to 2. (The example has a value of 0.) The value represents the filters model. filter model table: 0 Butterworth 1 Chebyshev 2 Bessel Note: when type = 2 (notch), element "model" must be 0 (Butterworth). Note: Not all filter parameters are applicabel to all types of filters. Despite, the parameters must be present. If a parameter is not applicabel e.g. frequency2 when using a highpassfilter, fill in some value. The value will be ignored but must be present in the file. Inside every element "signalcomposition", there can be one element with the name "ecg_filter", like: 1 The value of this element must be an integer with the value 1. (The example has a value of 1.) The value represents the activation of the heartrate detection. If the value of element "ravg_filter_cnt" is higher than zero, there must be at least one element with name "ravg_filter", like: The number of elements "ravg_filter" must be equal to the value of the element "ravg_filter_cnt". Inside every element "ravg_filter", there must be one element with the name "type", like: 0 The value of this element must be an integer in the range 0 to 1. (The example has a value of 0.) filtertype table: 0 higpass running average filter (also called: moving average filter) 1 lowpass running average filter Inside every element "ravg_filter", there must be one element with the name "size", like: 16 The value of this element must be an integer in the range 2 to 10000. (The example has a value of 16.) The value represents the size of the running average filterbuffer expressed in samples. Inside the root element "EDFbrowser_montage", there must be one element with the name "pagetime", like: 100000000 The value of this element must be an integer with a minimum value of 10000. (The example has a value of 100000000.) The value represents the timescale (pagetime) expressed in units of 100 nanoSeconds. Thus, a value of 100000000 means a timescale of 10 seconds. An example of the content of a montage file. --------------------------------------------- It contains three signalcompositions. All of them are derivatives of two signals: F4 - FP2, C4 - F4 and X1 - X2. The first signalcomposition has two filters: a 1th order highpass Butterworth filter at 0.1 Hz and a 1th order lowpass Butterworth filter at 35.0 Hz. ("frequency2" and "ripple" are not applicabel to this type of filter) The second signalcomposition has one filter: a notch filter at 50.0 Hz with a Q-factor of 20. The third signalcomposition has the heartrate detection activated. The timescale is set to 10 seconds. 2 50.000000 0.000000 2 2 0 1 -1 0 0.1000000000000000 0.1120000000000000 -1.0000000000000000 1 0 1 35.0000000000000000 39.2000000000000028 -1.0000000000000000 1 0 2 50.000000 0.000000 2 1 0 1 -1 2 50.0000000000000000 0.0001000000000000 -1.0000000000000000 20 0 2 5.000000 415.748031 7 0 0 1 -1 1 100000000 edfbrowser_153_source/doc/PaxHeaders.2978/manual.html0000644000175000001440000000013212251654530021057 xustar000000000000000030 mtime=1386699096.457032627 30 atime=1386699096.457032627 30 ctime=1386699096.457032627 edfbrowser_153_source/doc/manual.html0000644000175000001440000020631512251654530020617 0ustar00novarausers00000000000000 EDFbrowser manual

EDFbrowser 1.53 manual


Table of Contents:


Filemenu

Use the Filemenu to open or close a file. After the file has been opened,
the signaldialog will appear.


Table of Contents



Streaming mode

Use the Filemenu to open a stream. The stream must be a "growing" file.
This mode is used when you have an aquisitionprogram running that writes EDF or BDF.
While the aquisitionprogram writes the data to the file, you can use EDFbrowser to watch
(follow) the actual data. EDFbrowser will regularly check the actual filesize and show the
last part of the file i.e. the most actual/recent data.
The default intervaltime between the updates is 500 milliSeconds and can be changed in the settingsmenu.


Table of Contents



Signalsmenu

Use the Signalsmenu to add or remove signals. If you want to remove only one particular signal,
leftclick on the signallabel of the signal you want to remove. A small dialog will appear and gives
you the possibility to remove that particular signal from the screen. See also signaldialog.


Table of Contents



Timescalemenu

Use the Timescalemenu to choose the pagetime (the amount of seconds that must be shown on the screen).
Be aware that a pagetime of more than five minutes slowsdown the program. Specially when there are
many signals on the screen and/or high samplefrequencies.
"3cm/Sec" will adjust the pagetime so that one second equals 3 cm horizontally. In case you get a different
result, calibrate your screen in Menu -> Settings -> Calibration.


Table of Contents



Amplitudemenu

Use the Amplitudemenu to adjust the amplitude (size/gain/sensitivity) of all signals on the screen.
If you want to adjust the amplitude of one particular signal, use Signalproperties.
"Fit to pane" will adjust the height and size of all signals so that they will fit on the screen.
"Adjust offset" will adjust the height only (of all signals so that they will fit on the screen).
"Offset -> 0" will set the offset on the screen of all signals to zero.
Use the "+" or "-" keys on your keyboard to increase or decrease the amplitude of all signals.


Table of Contents



Signallabel

The signallabel is the name of the signal which is printed on the screen at the start of the trace.
This little piece of text has some "hidden" functions. When you leftclick on it, the Signalproperties
dialog will be opened. You can also drag this label with the left or right mousebutton to change
the offset or amplitude of the signal, see also Adjusting the position and size of the signals.


Table of Contents



Alias

The alias, if used, is an alternative signallabel which is printed on the screen at the start of the trace.
Aliasses can be created in the Signalproperties dialog and will be stored in your montage.


Table of Contents



Signaldialog

Use the signaldialog to add one or more signals to the screen. Go to Signals -> Add.
On top you will see a list of opened files.
Select (highlight) the file from which you want to add signals. At the left part of the dialog you see a list of
all the signals which are in the selected file. Select one or more signals and click on the "Add signal(s)"
button. Now you will see the selected signals on the screen. You can add more signals afterwards,
just go to Signals -> Add.

When you want to make a combination (derivation) of two or more signals, do as follows. Open the signalsdialog.
Select the file from which you want to add signals. In this example we choose an EEG file which contains
the signals "P3" and "C3" and we want to subtract "C3" from "P3".
- Select (highlight) the signal "P3".
- Click on the "Add" button.
- Select (highlight) the signal "C3".
- Click on the "Subtract" button.
- Click on the "Make derivation" button.
- The result of "P3" minus "C3" will appear on the screen.

Now you can add more combinations or simply close the dialog.

note: It is only possible to make combinations with signals who:
- are in the same file
- have the same samplerate
- have the same physical dimension (e.g. uV)
- have the same sensitivity (e.g. uV/bit)

note 2: If you want to invert the signals (which is common in EEG) do as follows:
instead of P3 - C3, use -P3 + C3 (or C3 - P3).
You can also invert a signal afterwards, go to Signals -> Organize.


Table of Contents



Signalproperties

You can view or adjust the properties of a specific signal by leftclicking on the signallabel.
A small dialog will be opened and let you change the amplitude and color.
You can also remove filters (if any) or remove the signal from the screen.
You can also enter an alias for the signalname.
Another option is to activate one or more crosshairs for precise measurements.

Another way to view/change the properties of a signal is to go to Signals -> Properties.
This will show you a list of all signals which are on the screen. Simply click on the
signal of interest.


Table of Contents



Adjusting the position and size of the signals

Leftclick on the signallabel and move the mousepointer up or down while keeping the
left mousebutton pressed. This will move the signal up or down on the screen i.e. it
changes the offset of the signal.

Rightclick on the signallabel and move the mousepointer up or down while keeping the
right mousebutton pressed. This will increase or decrease the amplitude (size/gain) of
the signal on the screen.


Table of Contents



Organize signals

You can organize the signals via Signals -> Organize.
Here you can change the order of the signals on the screen, remove or invert signals.


Table of Contents



Navigation

Navigation throug a file can be done by using the PageUp/PageDown buttons on your keyboard.
Use the Arrowkeys to shift the screen one tenth of the pagetime. The mousewheel can be used to
scroll horizontally. The stepsize of the mousewheel can be set in the settings menu.
A value of zero disables mousewheel scrolling.

You can also zoom-in.


Table of Contents



Annotations

When a file contains annotations, the annotationwindow will appear.
Just click on one of the annotations to jump to that position in the file.
This window is dockable. You can change the size of the window, but also the position.
You can make the window floating as well by dragging it with the mouse. After closing
the annotationwindow, you can make it appear again via Window -> Annotations.

By right-clicking on an annotation in the annotationwindow, you can hide or unhide one or more
annotations from the screen.


Table of Contents



Filters

Use the filtermenu to add or remove filters. First select the type of filter: highpass, lowpass, notch, bandpass or bandstop.
Now select the model: Butterworth, Chebyshev, Bessel or "moving average" (a notchfilter has resonator model only).
Then set the frequency(s) of the filter (or number of samples in case of a "moving average" filter).
Depending on the type and model of the filter, you can adjust the order, Q-factor and passbandripple.

The curve will show the frequency and phase response of the filter (except for "moving average" filters).

Now select one or more signals to apply to and click the "Apply" button.

Reviewing the filters can be done in the Montage -> View this montage menu.

Algorithm for the moving average filters:
LPF: the mean of the last n data samples.
HPF: last-n/2 sample minus the mean of the last n data samples.


Table of Contents



Adjust filters

You can adjust or finetune the filters. Left-click on a signallabel and select "Adjust filter".
You can adjust or finetune the frequency, order or Q-factor of a filter and watch the result at the same time.


Table of Contents



Powerspectrum

To view the powerspectrum of a signal, leftclick on the signallabel and choose "Spectrum".
The Power Spectral Density of the corresponding signal will be shown (uV)2/FFT-resolution.
The amount of datasamples used to perform the FFT equals the data which is
shown on the screen. Increasing or decreasing the FFT blocksize affects the FFT resolution.
The FFT blocksize can be set in Settings menu.
This powerspectrum is static and will not update when you change the fileposition (pressing PgUp/PgDn etc.).
This way you can compare multiple powerspectra from different signals and/or filepositions.

There is also a powerspectrum window available that automatically updates when you walk through a file.
Go to Window -> Spectrum.
A small dialog will be opened which shows a list of signals which are on the screen.
Click on a signal of interest and a docked Powerspectrum (FFT) will be opened.
This Powerspectrum will be automatically updated when you navigate through the file. Clicking on the
"ctls" button toggles the controls. Here you can switch-on colorbars to highlight different frequency-
regions. The properties of the colorbars (number of colorbars, frequency, color, etc.) can be adjusted
in the Settings menu. The height of the colorbar is relative to the sum, peak or average of the the
power of all the frequency-bins in that region, according to the settings in the Settings menu.
Use the sliders to zoom into a particular area.
When you check the "Amplitude" checkbox, the amplitude spectrum will be shown.
Printing can be done by clicking on the printbutton. You can print to a printer, file (PDF or Postscript)
or as an image. It is also possible to "print" to a textfile. It exports the data to text (ASCII).
Clicking on the cursorbutton will display a cursor. Use the mouse to drag the cursor.


Table of Contents



Averaging (evoked potentials or other triggers)

Averaging waveforms (multiple parts of a signal) can be done by rightclicking on an annotation (trigger) in
the annotationlist. A contextmenu will be opened, now click on "Average".
The timescale (datablocksize) of the averaging window will be equal to the timescale of the mainwindow.
So, if you want to average 20 seconds, set the timescale to 20 first.
A dialog will be opened where you can choose to which signal you want to apply the averaging.
If necessary, change the "From"- and "To"-times in order to select a particular group of triggers.
Only the triggers with an onsettime that lies between the two timevalues will be used for the averaging.
Select the ratio of the time before and after the triggerpoint. For example, if the timescale of the mainwindow
is set to 20 seconds and you select a 10/90 ratio, averaging will start 2 seconds before the triggerpoint and
stops at 18 seconds after the triggerpoint.
Now click on "Start" and a new window will be opened which will show the result of averaging
all signalparts of all annotations (triggerpoints) with that specific name.
The yellow colored, dashed, vertical line is the triggerpoint, i.e. the onsettime of the annotations (triggers).
Use the sliders to zoom into the signal. The timescale is relative to the trigger (onset) point.

The result can be printed or exported as a new EDF/BDF file.

You can also use external triggers in ASCII(*.csv or *.txt) or XML format.
See Import annotations/events how to import triggers/events/annotations.

Note: It is also possible to change the selection of annotations/triggers for averaging, by editing the annotationlist first.


Table of Contents



ECG heart rate detection

Toggling the "Heart Rate" button toggles on or off the detection and calculation of the heartrate
expressed in beats per minute (bpm).
The "Heart Rate" button can be found in the Signalproperties dialog.
The algorithm used for the heartrate detection is derived from "Real time electrocardiogram QRS detection using combined adaptive threshold"
by Ivaylo I Christov. http://www.biomedical-engineering-online.com/content/3/1/28

The R-onset times and/or RR-interval times (beat to beat) can be exported to an ascii-file for analysis in other programs (e.g. Kubios).
After you switched on the Heart Rate detection, go to "Tools -> Import/Export ECG RR-interval".
Only the part of the signal that is visible on the screen will be exported, except when you check the "Whole recording" checkbox.
There is also the possibility to import the RR-intervals as annotations.

Some statistics about the Heart Rate (variability) are available here.

Important: before using the Heart Rate detection, go to the settings menu (Settings -> Other) and adjust the "Powerline Frequency" to the frequency used in the country
where the recording of the ECG took place (50 or 60 Hz). Otherwise the powerline noise suppression filter in the Heart Rate detection algorithm will not work correctly.


Table of Contents



Heart Rate statistics

When the ECG heart rate detection is enabled, you can view some statistics about the
Heart Rate (variability) in the Signalproperties. Once you see the Signalproperties dialog,
click on the "Statistics" button. A brief description of the statistics:

- Mean, the average of the RR-intervals.
- SDNN, the standard deviation of RR-intervals.
- RMSSD, the square root of the mean squared difference of successive RR's.
- NN50, the number of pairs of successive RR's that differ by more than 50 ms.
- pNN50, the proportion of NN50 divided by total number of RR's as a percentage.

The data used for the statistics is derived from the timewindow that is visible on the screen.


Table of Contents



Zoomfunction

There are multiple ways to zoom-in:

- By pressing (several times) Ctrl++ or Ctrl+-.

or

- By using the mousewheel while keeping the Ctrl-button pressed.

or

- You can zoom into a signal/curve on the screen by drawing a rectangle with the mouse.
Keep the left mousebutton pressed and move the mousepointer in the direction of the
right lower corner. When you release the left mousebutton, the content of the rectangle
will be expanded to the whole screen. You can repeat this step and zoom in again.

Use the backspace button on your keyboard to zoom out and restore the previous settings.
After using the backspace button, you can zoom in again by pressing the insert button on
your keyboard.


Table of Contents



Floating ruler

You can use a floating ruler for measurements. Leftclick on the signallabel of the signal
of interest. A small dialog will appear. Click on Ruler. A floating ruler will appear.
Drag and drop the ruler with the left mousebutton. Rightclick to remove the ruler or press the "Esc" key.
Note: the ruler will appear only when the Timescale (pagetime) is set between 2 and 60 seconds
AND when the amplitude (size/gain) is set between 1 and 2000.


Table of Contents



Crosshairs

You can use one or two crosshairs for precise measurements. Leftclick on the signallabel
of the signal of interest. A small dialog will appear. Click on Crosshair. A crosshair will
appear. Drag and drop the crosshair with the left mousebutton. Now you can add another crosshair.
The second crosshair will show you the differences (delta) in time and value of the signal(s).
Rightclick to remove the crosshair(s) or press the "Esc" key.


Table of Contents



Statistics

Some statistical info about a signal can be found in the Signalproperties.
and clicking on the "Statistics" button. It will show the number of samples showed on the screen, the sum, mean, RMS (root mean square), and MRS
(mean root square i.e average of rectified values) value of the samples showed on the screen.
In addition, the number of zero-crossings (i.e. switching from positive to negative or vice versa)
and the frequency of that part of the signal will be shown.


Table of Contents



Montages

Montages can be used to store information about which signals should be shown on
the screen, what combinations (derivations) should be made and other properties
like filters, amplitude (sensitivity), offset, alias, color and pagetime (timescale).
Once you have loaded a file for review and you have added all the signals you want
(and/or all the combinations/derivations) and you have adjusted amplitude and colors
and/or filters, you can save them as a montage.
Go to Montage -> Save. A dialog will be opened where you can choose a directory
and filename to store your montage.
Next time when you load a file, you can load a montage via Montage -> Load.

You can view the properties of a montage via Montage -> View saved montages or
Montage -> View this montage.

note:
It is important that the names (labels) of the signals are correct when you use a montage
to review different files.

You can bind the F1 to F12 keys to twelve different montages. This way you can quickly switch
between different montages by pressing key F1, F2, etc.
Go to Montage -> Edit key-bindings for montages.


Table of Contents



Keyboard bindings for montages

It is possible to create keyboard shortcuts (bindings) for predefined montages.
Go to Montage -> Edit key-bindings for montages. Click on the first row (F1);
Now you can select a montage. You can assign twelve different
montages to keys F1 - F12.
Now you can quickly switch between predefined montages by pressing one of these keys.


Table of Contents



Colors

Go to the Settings menu to change the colors like you prefer.


Table of Contents



Calibration

In the Settings menu go to the Calibration tab to calibrate your screen.
This will achieve that the amplitude expressed in units/cm will have
the correct height/value.


Table of Contents



Timelock and File synchronisation

When you open multiple files, you can choose to "timelock" all files with
each other. This means that when you navigate (by pressing PgUp/Pgdwn)
this will affect all signals on the screen. When you choose to "unlock" the files,
only the signals of the "reference" file will be moved on the screen. You can
change which file should be the reference in the Time-menu.

There are three kinds of timelock:

- Offset

The start of the recording of all files will coincide with each other.

- Absolute time

The clock/date-time of the different files will coincide with each other.
(this is only useful when the period of registration overlap eachother)

- Userdefined synchronizing

When this setting is selected, only the signals from the file that has the
"time reference" will move when you navigate.
Use this option when you want to align two or more files manually.


The time shown in the leftbottom corner represents the time from the
file that acts as the "reference". You can change which file should be
the reference in the Timenu.

You can adjust the horizontal position (time) of two different files by using
two crosshairs. Put one crosshair at a signal of the first file and put the second
crosshair at a signal of the second file. Now click on Time -> synchronize by crosshairs.
Now the position of the two crosshairs (and that particular position of the two files) will
coincide with eachother.


Table of Contents



File info / properties / header

To view the content of the header of a file (subject, recording, signalproperties like samplerates etc.),
go to file -> info and select the file of interest.


Table of Contents



Header editor

This tool can be used to edit (or anonymize) the header (file info) like subject, birthdate, etc.
You can also edit labels (signalnames), physical dimension, pre-filter and transducer names.
If the file you want to edit has been opened in EDFbrowser already, close it first before starting
this tool.
This tool can also be used to repair a file that can not be opened with EDFbrowser because of
invalid characters in the header (the EDF format allows 7-bit ascii characters only) or other errors.

Other errors that can be fixed with this tool:
- a wrong timestamp format in the header (a colon instead of a dot between the numbers)
- a wrong number of datarecords written in the header
- a wrong filesize (file is not ending on the boundary of a datarecord)
- a broken number i.e. a number with decimal(s) in the digital maximum/minimum field

Do as follows: In EDFbrowser go to Tools -> Header editor. Select the file. Now click on the
"save" button (you don't need to edit the content manually). Close the header editor.
Now open the file in the usual way.


Table of Contents



EDF(+)/BDF(+) to ASCII format converter

This tool converts all the signals in an EDF or BDF-file to a plain ASCII text-file.
It supports different samplerates between the signals.

Four textfiles will be created:

- EDFfilename_header.txt contains the general header of the file.
- EDFfilename_signals.txt contains all signal headers of the file.
- EDFfilename_data.txt contains the data of all signals.
- EDFfilename_annotations.txt contains all annotations.

filename_data.txt contains a separate line for each sampletime that occurs.
Note to windows-users: these lines are separated by a linefeed only,
so the file does NOT look OK in Notepad, use Wordpad instead.

Each line contains the comma-separated values of the sampletime and of all
samples that were taken at that time.
Sampletime is expressed in seconds, while sample values are expressed in the
physical dimensions that are specified in filename_signals.txt.
All values have a dot (.) as decimal separator.

Different sampling frequencies are allowed in the file. In that case,
not all signals are sampled at each sampletime.
Those sample values are simply left empty, but the comma-separator is there.

note:

All comma's in headertext and annotations will be replaced by
single quotes (') because they interfere with the comma-separated
txt-files.

Unicode/UTF-8 decoding in annotations is not supported because of
the limitations of the ASCII txt-files.


Table of Contents



Reduce signals, duration and/or samplerate

This tool can be used to reduce the number of signals in a file and/or to reduce the duration (length) of a file
and/or to reduce the samplerate of one or more signals.
First, open the file in the usual way in EDFbrowser. Then start the tool and select the file.
Uncheck all the signals you do not want into the new file. If you want to shorten the file, choose the first
datarecord (starttime) and the last datarecord (endtime).
If you don't want to downsample, set the samplerate divider to 1 (default). Otherwise select one of the possible
divider values. Those values depend on the actual samplerate and the datarecord duration.


Table of Contents



Export annotations/events

This tool exports the annotations/events from an EDF+/BDF+ file.
You can choose to save as a comma (or tab) separated textfile, to save as an EDFplus file
or XML. If you have opened multiple files, you can choose to export all
annotations of all opened files into one new file. The header of the file which acts as
the "reference" will be copied into the new EDFplus file. The "reference" file can be selected
in the menu Time -> Timereference.


Table of Contents



Import annotations/events

This tool imports annotations/events. The inputfile can be ASCII (CSV), XML, EDF+ or BDF+.
It's also possible to use a triggersignal in a DC-coupled channel/signal.

ASCII

An ASCII-file must be organised in rows and columns.
In the import dialog, set the separatorcharacter (the character that separates the columns),
for example: "tab" (tabulator) or "," (comma).
Also, set the columnnumber of the onsettime and the description/label.
If the file starts with a header, adjust the "Data starts at line" spinbox
in order to skip these lines.
If there's only one column in the ascii/txt file (with onset time values), check the
"Manual description" button and enter a description. This description will be used for all
annotations that will be imported from that ascii/txt file.

XML

XML-files need to be encoded either in ISO-8859-1 or UTF-8 character encoding.
The root element name must be "annotationlist", child elements must be named "annotation".
Inside the element "annotation" are the elements "onset", "duration" and "description".
Onset is expressed in the ISO date-time format "yyyy-mm-ddThh:mm:ss" or "yyyy-mm-ddThh:mm:ss.xxx".
Duration is expressed in seconds "145.23" or empty.
Example:

<?xml version="1.0" encoding="UTF-8"?>
<annotationlist>
 <annotation>
  <onset>2006-11-14T09:14:31.0000000</onset>
  <duration></duration>
  <description>REC START IIB CAL   </description>
 </annotation>
 <annotation>
  <onset>2006-11-14T09:14:31.0000000</onset>
  <duration></duration>
  <description>PAT IIB EEG         </description>
 </annotation>
 <annotation>
  <onset>2006-11-14T09:14:32.0000000</onset>
  <duration></duration>
  <description>A1+A2 OFF           </description>
 </annotation>
</annotationlist>

Note: You have to open an EDF/BDF file first in order to be able to import annotations/events.

DC-events / DC-triggers

A "DC-event" consist of a positive impulse (startbit) followed by eight databits and a stopbit (lowlevel).
This signal is recorded onto a dc-coupled inputchannel of the hardware during aquisition.
The eight databits are used to identify a maximum of 256 different types of events/triggers.
The startbit has always a high level and the stopbit has always a lowlevel.
At idle the signal should stay at low level.
The following example shows a dc-event with decimal code 170:

                  onsettime of the event
                  |                               bittime
                  |                               |<->|
                  v                               |   |
 1 Volt           +---+   +---+   +---+   +---+   +---+
                  |   |   |   |   |   |   |   |   |   |
                  |   |   |   |   |   |   |   |   |   |<--triggerlevel = 0.5 Volt
                  |   |   |   |   |   |   |   |   |   |
 0 Volt ----------+   +---+   +---+   +---+   +---+   +---+--------------
            ^       ^   ^   ^   ^   ^   ^   ^   ^   ^   ^
            |       |   |   |   |   |   |   |   |   |   |
            idle    |   |   |   |   |   |   |   |   |   stopbit, always low
                    |   |   |   |   |   |   |   |   db7
                    |   |   |   |   |   |   |   db6
                    |   |   |   |   |   |   db5
                    |   |   |   |   |   db4
                    |   |   |   |   db3
                    |   |   |   db2
                    |   |   db1
                    |   db0
                    startbit, always high

The binary code in the example is 01010101 which is 170 decimal.
The rising edge of the startbit represents the time of the event (for example, an evoked potential).
The voltage levels can be freely chosen. In the importdialog adjust the triggerlevel to a level that is equal
to: (lowlevel + highlevel) / 2.
Also, set the bittime used for the DC-event.
Note that the intervaltime between two consegutive events must be more than ten times the bittime.

It is possible not to use the code but just only the startbit. In that case all triggers will have the code "0".
In that case you can use a simple on/off pulse as a trigger.

Note: The signal which contains the DC-event must be put on the screen in order to be available in the selectionscreen.
Also, the signal must be unipolar, i.e. not a derivation. Next, the detectionalgorithm of the triggers in this signal will bypass
any filters.


Table of Contents



Z-EEG

To use the Z-EEG measurement, leftclick on the signallabel and choose "Z-EEG".

Z-ratio = ((Delta + Theta) - (Alpha + Beta)) / (Delta + Theta + Alpha + Beta)

Z-ratio, therefore, is a measure of the relative contribution of slow to fast EEG activity within a
2-second epoch. It ranges from -1 to +1, with negative values indicating a predominance of fast
activity and positive values indicating a predominance of slow activity.

A per page score for z-ratio was derived by averaging the majority of 15 2-second z-ratios.
The average of the majority is the z-page.

The algorithm is derived from

http://www.ncbi.nlm.nih.gov/pubmed/8746389/

http://www.zzzratio.com/Z-bib.pdf


Table of Contents



ASCII to EDF/BDF format converter

This tool converts an ASCII-file (.csv or .txt file) to EDF or BDF. The following rules apply:

- the data in the ASCII-file must be presented in their physical dimension (i.e. uV, bpm, mmHg, etc.)
- the data in the ASCII-file must be organised in columns and rows
- a row must contain values from different signals/channels aquired at the same sampletime
- a column must represent a continuous sampled signal/channel
- all signals/channels must have the same samplefrequency
- the timeinterval between two consecutive samples of the same signal/channel must have a stable value (fixed samplerate)

Enter the following parameters:

- the character that separates the different columns (i.e. "tab" ","(comma) ";"(semicolon) " "(space) etc.)

- the number of columns

- the line at which the data starts. some ASCII-files contain headers, so use this entry
to tell the converter to skip n-lines before interpreting the data

- samplefrequency

- subject (the name of the subject)

- recording (a description about the type of recording/aquisition)

- startdate and time of the recording/aquisition

- signals: for every column in the ASCII-file, there is a row in the signals-table.
every row has a checkbox and four inputfields:

- label (name of the signal/channel i.e. FP1, SaO2, Heartrate, etc.)
- physical maximum (the maximum physical value that can occur, i.e. the maximum inputlevel
of the aquisition equipment. A common value in EEG applications is 3000 uV)
physical minimum will be equal to physical maximum. for example, if you enter 3000, the
range will be from +3000 to -3000
- physical dimension (i.e. uV, %, mmHg, bpm)
- multiplier is normally 1.0. Some programs exports their ascii-data expressed in Volts while
the signal is in the microVolt range. By changing the multiplier you can add gain to the signal before converting.
For example, if the ascii-data is expressed in Volts and the signal is in the microVolt range (EEG),
set the physical maximum to 3000, set the physical dimension to "uV" and set the multiplier to 1000000.

It is possible to exclude columns, by unchecking the corresponding row in the signals-table,
this can be useful when a column contains a time/datestamp or when you don't want to include
a particular signal in the EDF/BDF-file.

Click on the startbutton to start the conversion.
Click on the savebutton to save the entered parameters in a template.
Click on the loadbutton to load parameters from a template.

Note: It is important to enter the right value in the "physical maximum" field.
If you to choose this value too small, the top of the signal will be cut off.
If you choose this value too big, small values of the signal will not be visible
and the signal will look coarse.
The ideal value for the "physical maximum" is just above (or equal to) the maximum value that can occur,
i.e. the maximum possible output of the sensor or ADC, either positive or negative.
Therefore, it's better to set the checkbox "Auto detect physical maximum". That way you don't need to
enter the values in the column "Physical maximum".

Note 2: The maximum physical value that the converter can handle, is limited to 9999999. Values above
will be clipped to 9999999 and values below -9999999 will be clipped at -9999999.
If you expect higher values in your ascii-file, use the multiplier. For example,
set the multiplier to 0.1, 0.01 or 0.001, etc.

Note 3: If you think that, later, you want to make derivations (for example P4 - C4 in EEG applications),
make sure that the signals have the same value in the physical maximum field.
Also, do not set the checkbox "Auto detect physical maximum".


Table of Contents



Nihon Kohden to EDF(+) format converter

This tool converts EEG-files in Nihon Kohden format to the European Data Format
(EDF or EDF+ with annotations/events).

Three files are needed for a conversion to EDF+:

- nihonkohdenfile.eeg
- nihonkohdenfile.pnt
- nihonkohdenfile.log

In case you have only the nihonkohdenfile.eeg you can not convert to EDF+.
It is still possible to convert to EDF. In that case there will be no annotations/events and patientinfo.

The Marker/Event channel will be decoded on the fly when opening the new created EDF+ file with EDFbrowser.
If the screen becomes too "noisy" because of drawing too many annotations, you can switch them of by
unchecking the "Read Nihon Kohden Trigger/Marker signal" checkbox in the Settings-menu.
The new settings will be effective after closing and re-opening the file.
Also, you can selectively hide annotations by rightclicking on an annotation in the annotationwindow.

Note: In case you changed the default electrodenames in the Nihon Kohden aquisition software,
you need also the *.21e file which contains the electrode names (labels).


Table of Contents



Unisens to EDF+ format converter

This tool converts the waveform data and events/triggers from a collection of Unisense data files to EDF+.

Limitations of the converter:
- the following binary sampletypes are not (yet) supported: int64, uint64 and double.
(double is supported in csv-files)
- the Unisens XML-file must be encoded in UTF-8 or ISO-8859-1.
- Broken numbers for samplerate >= 1 Hz will be rounded to the nearby integer e.g. 2.75 Hz will be rounded to 3 Hz.
Samplerates below 1 Hz will be rounded to 1/2, 1/3, 1/4, etc. til 1/1000 Hz.
Lowest samplerate is 0.001 Hz
- Output format of the converter is EDF+ (16-bit) when all files have a samplesize of 16-bit or lower.
When one or more files have a samplesize of more than 16-bit, output format of the converter will be BDF+ (24-bit).

An extra feature of the converter which is not in the offical Unisens data format specification:
- support for binary sampletypes: int24 and uint24.


Table of Contents



SCP ECG to EDF+ format converter

This tool converts the waveform data of an SCP ECG file to EDF+.
Before conversion it performs a CRC-check on the file.
Encoding using the default Huffman table is supported.
Customized Huffman tables are not supported.
Bimodal compression is not supported. Character-encoding other than ASCII/Latin-1 is not supported.


Table of Contents



Manscan to EDF+ format converter

This tool converts a Manscan MICROAMPS binary data file to EDF+.
Two files are needed for the conversion, one with the extension ".mbi" and one with the extension ".mb2".


Table of Contents



Biosemi to BDF+ format converter

This tool converts a Biosemi data file to BDF+ and makes it possible to visualize the
trigger interrupts and the "new epoch" in EDFbrowser.
The Status signal of the Biosemi datafile which contains the input triggers will be
converted to annotations in the BDF+ format. The original file will not be altered.
Instead, a copy of the file will be made in the BDF+ format which will contain annotations
extracted from the Status signal (which contains the input triggers).
The original Status signal will be preserved in the new file.
You'll find the Biosemi to BDF+ converter in the Tools-menu.

BDF+ files are backwards compatibel and can be read and processed with older BDF software.
BDF+ files can be converted to EDF+ while preserving your annotations.
Use the BDF to EDF converter in the Tools menu.

Limitations:

- The maximum number of annotations (input triggers) in the new file is:
  duration of file in seconds multiplied by 32. If the original file contains more trigger input events, they will be ignored.
  If, for example, the duration of a file is 5 minutes, the first 9600 input triggers will be converted to BDF+ annotations.

- The precision of the annotations is limited to 100 microSeconds (0.0001 sec.).

- Only the 17 lowest bits of the Status signal will be evaluated and converted.


Table of Contents



Finometer to EDF converter

This tool converts the ASCII-output (*.txt) of the Finometer (Beatscope) to EDF.
Finometer is a non-invasive stationary blood measurement and beat to beat haemodynamic monitoring system
made by Finapres Medical Systems.

Start Beatscope and open the file of interest.

Go to File -> Export.

- set export type to textfile
- set timeformat to seconds
- check output: header
- set averaging to none
- check datacolumnwidth: delimiter
- set delimiter to semicolon ";"
- check export beats and/or events: beats only
- select the channels you want to export

Now click on the Export-button to create the file.

In EDFbrowser, you'll find the Finometer to EDF converter in the Tools-menu.
In order to create a correct EDF-file header, enter the subject and a description about
the type of recording/aquisition.
Adjust the startdate and starttime to the date and time when the Finometer registration took place.

Click on the "select file" button to select the Finometer/Beatscope file.


Table of Contents



Wave to EDF converter

This tool converts a Waveform Audio File (*.wav) to EDF.
The converter accepts 8, 16 and 24 bit wave files.
It accepts 1 to 256 channels and samplerates from 1 Hz to 500000 Hz.
8 and 16 bit wave files will be converted to EDF. 24 bit wave files will be
converted to BDF. Compressed files are not supported.


Table of Contents



Nexfin to EDF converter

This tool converts the ASCII-output (*.csv) of the Nexfin (FrameInspector) to EDF.
Nexfin is a non-invasive stationary blood measurement and beat to beat haemodynamic monitoring system
made by Bmeye B.V.

Start FrameInspector (it can be downloaded from the Nexfin website), open the file of interest and
choose "Generic export".

Now click on the Export-button to create the csv and bin files.

In EDFbrowser, you'll find the Nexfin to EDF converter in the Tools-menu.
In order to create a correct EDF-file header, enter the subject and a description about
the type of recording/aquisition.
Adjust the startdate and starttime to the date and time when the Nexfin registration took place.

Select which file you want to convert: beat-to-beat data, blood pressure waveform or the analog inputs.
(for analog inputs: select "4 inputs" in case AO option is configured, else "1 input")
Click on the "select file" button to select the Nexfin/FrameInspector csv or bin file.
For beat-to-beat data you need to select the file that ends with "_100.csv".
For blood pressure waveform you need to select the file that ends with "_103.bin".
For the analog inputs you need to select the file that ends with "_032.bin".


Table of Contents



Emsa to EDF+ format converter

This tool converts an Emsa eeg-file (*.PLG) to EDF+. If the corresponding *.LBK file is
present, the annotations/events will be exported to EDF+ as well.


Table of Contents



EDF+D to EDF+C converter

This tool converts an EDF+D file to multiple EDF+C files. An EDF+D file can contain
interrupted recordings. This converter export every uninterrupted recording to a new
uninterrupted EDF+C file.
This tool can be used for BDF+D files as well.


Table of Contents



BDF(+) to EDF(+) converter

This tool converts a BDF file to an EDF file. A BDF+ file will be converted to
EDF+, including the annotations/events.
It uses a first order highpass-filter to remove the DC-part of the signal in order
to make the 24-bits samples fit into the 16-bits samples of EDF.
The cutoff-frequency of the highpass-filters can be adjusted for every signal.
You can also select which signals have to be converted into the new EDF(+) file.
Increasing the divider lowers the resolution but increases the range (physical
maximum and minimum)


Table of Contents



EDF(+) and BDF(+) compatibility checker

This tool checks if a file is EDF(+) or BDF(+) compliant.
It checks the data and all the annotations and timestamps.
When it finds an error, it tells you what the error is and where it is in the file.

A description of the EDF fileformat can be found at:

http://www.teuniz.net/edfbrowser/edf format description.html

A description of the EDF+ fileformat can be found at:

http://www.edfplus.info/specs/edfplus.html

A description of the BDF fileformat can be found at:

http://www.biosemi.com/faq/file_format.htm

A description of the BDF+ fileformat can be found at:

http://www.teuniz.net/edfbrowser/bdfplus format description.html

note:

A compatibility check of the header of the file is always done when you open an
EDF(+)/BDF(+) file. When a file appears to be incompatible it will not be opened,
you will be informed about the cause of the incompatibility instead.

Note: If a file can not be opened with EDFbrowser because of invalid characters in the header
(the EDF format allows 7-bit ascii characters only), you can try to fix it with the header editor.
In EDFbrowser go to Tools -> Header editor. Select the file. Now click on the "save" button
(do not edit the content!). Close the header editor. Now open the file in EDFbrowser.


Table of Contents



Binary/raw to EDF

This tool converts the binary (raw) (ADC-)data from a file to a new EDF-file.
This is a kind of "last resort" measure when there are no other tools or EDF-converters available.
You need to figure out how the data in your file is organised and you need to have a good knowledge of
how computers store data in memory (file). This tool is for experts only.

All signals must have the same samplerate and the data-samples in the file must be stored sequentially:
sample 1 ch.1, sample 1 ch.2, sample 1 ch.3,
sample 2 ch.1, sample 2 ch.2, sample 2 ch.3,
sample 3 ch.1, sample 3 ch.2, sample 3 ch.3,
sample 4 ch.1, etc.

Set the samplefrequency and the number of signals (channels).
The samplesize is the size of a digital sample expressed in bytes.
Encoding is the binary system used to present a digital value:

  value   bipolar offset binary    2's complement
15 1111 0111
14 1110 0110
.... .... ....
2 1010 0010
1 1001 0001
0 1000 0000
-1 0111 1111
-2 0110 1110
.... .... ....
-15 0001 1001
-16 0000 1000
See also: Coding Schemes Used with Data Converters
Most files contain some kind of header. Adjust the Offset to the point where the data starts.
When a digital sample consists of multiple bytes, and the LSB (least significant byte) comes first,
select little Endian. If the MSB (most significant byte) comes first, select big endian.
Data blocksize is usually 0. Used only when some bytes must be skipped in a regular interval.
Skip bytes is the number of bytes that must be skipped (ignored) after every Data blocksize number of databytes.
Skip bytes is ignored when Data blocksize is set to 0.


Table of Contents



Print to PDF

You can print/export to PDF in File -> Print -> to PDF


Table of Contents



Print to image

You can print/export to an image in File -> Print -> to Image


Table of Contents



Print to EDF

The option "Print to EDF" creates a new EDF-file which will contain the signals
(and annotations) as they are on your screen. What you see is what you get,
like when you print to a printer, PDF-file or image. You can also open multiple
files, shift them in time (by using the different timelock options in the timemenu)
and "print" the result as one new EDF-file. The result wil contain the time-shifted
signals.
It is also possible to extract one or more signals from one (or more) files into a new file.

This function is located in File -> Print menu.

The following rules apply:

- the length (duration) of the new file will be equal to the selected displaytime (timescale)

- combined signals (derivations) will become one signal like they are on your screen

- in case of multple files, the new file will get the subject, recording, date and time
of the file that has the reference at the moment of printing.
You can select the reference in the Time-menu

- if (one of) the file(s) is of type EDF+, the outputfile will be an EDF+ file as well,
otherwise EDF

- when selected multiple files, the datarecordduration of these files
needs to be the same or an integer multiple of eachother

- if you selected any filters, these will be applied as well


Table of Contents



Print to BDF

The option "Print to BDF" creates a new BDF-file which will contain the signals
(and annotations) as they are on your screen, in the same way like the Print to EDF function,
except that it is also possible to print EDF(+) files to BDF. You can even mix
EDF and BDF files onto your screen and print them to a new BDF file.


Table of Contents



Annotation editor

The annotation editor can be used to add, remove or edit annotations.
Start the editor via menu -> Window -> Annotation editor.
To create a new annotation, write the text of the annotation in the description window and set
the onset time. You can set the duration time as well. If the duration time is unknown or not
applicable, set it to the value -1. Now click on the create button.

Instead of manually entering the onset time, you can use a crosshair.
Drag and drop the crosshair and the onset time will be automatically adjusted.
You can use a second crosshair to adjust the duration time.

To modify an existent annotation, click on the annotation in the annotation window.
Adjust the text and or time, manually or drag and drop the annotation marker.

To delete an annotation, click on the annotation in the annotation window and click
on the delete button.

When you are finished editing annotations, save the file in menu -> File -> Save.
Your file will not be altered, instead a copy of your file with the edited annotations
will be made.

Note: The annotation editor will limit the precision of the onset-time of the annotations
to 1 milliSecond.


Table of Contents



Commandline options

edfbrowser [datafile.edf] [mymontage.mtg]

It is possible to start the program from the commandline:

edfbrowser.exe

this will start the program.

or

edfbrowser.exe myfile.edf

this will start the program with the file myfile.edf opened.

or

edfbrowser.exe myfile.edf mymontage.mtg

this will start the program with the file myfile.edf opened and using the montage mymontage.mtg.


Table of Contents



FAQ


Q. How do I add signals to the screen?

A. Use the signalsdialog.


Q. How can I change the amplitude of a signal?

A. Leftclick on the signallabel of that signal. A small dialog will appear. There is a
spinbox that will let you change the amplitude of the signal.
Another way is to rightclick on the signallabel and move the mousepointer up or down
while keeping the right mousebutton pressed. This will increase or decrease the amplitude
of the signal on the screen.

Q. How can I see the value of a signal?

A. Use a crosshair.


Q. I added signals from multiple files but some of them are not visible on the screen.

A. Go to the "Time" menu and set it to "Synchronize start of files".
Then select Time -> Go to start of file.
Now select Amplitude -> Fit to pane.


Q. I want to open two files in different windows.

A. Start the program twice and you can open files in different windows.


Q. When I try to open a file, it says that the file is not EDF(+)/BDF(+) compliant.
What do I do?

A. Try to find out what program created that file. Write the maker/developer of that
program and tell him/her that the program does not produce valid EDF(+)/BDF(+) files.
Ask him/her to fix that program.
If you get the message that a character in the header is not a valid ASCII-character,
use the header editor to repair your file.

Q. How can I combine multiple EDF/BDF files?

A. Use the Print to EDF function.


Q. What is the difference between EDF and BDF?

A. The difference is the resolution. In EDF the maximum resolution is 16 bits, so the ratio
between the smallest and the largest value is 1 to 2^16 or 1:65536.
In BDF the resolution is 24 bits, so the ratio between the smallest and the largest value is
1 to 2^24 or 1:16777216. In other words, the dynamic range of a BDF file is much higher.
BDF is the 24-bits version of EDF, invented because more and more ADC's/aquisition systems use
24-bits analoog to digital converters. When you try to store the data from a 24-bits ADC into EDF,
you will lose information.


Q. When I print a file, the borders are cut away (the first characters of the signallabels are missing).

A. In the printerdialog, choose "landscape" and the right papersize (A4) and
adjust the margins in the printerproperties.
For example, set top and bottom margins to 0.85 cm and the left and right margins to 1.27 cm.


Q. When I print to a PDF file, the traces look grey instead of black when I open the file
in Adobe Reader 8.x.

A. In Adobe Reader, go to Edit->Preferences->Page Display and uncheck "Smooth line art".


Q. Why are the annotationmarkers not visible?

A. Go to the Settings menu. Check "Annotation marker" and make sure that it
has a different color than the background color.


Q. The amplitude settings are not correct. For example, 100 uV/cm is 100 uV/1.5 cm.

A. This can happen when the DPI-settings of the operatingsystem are wrong. For example,
when EDFbrowser can not read your monitorsettings or when the monitorsettings are wrong.
You can solve this as follows. Go to the settingsmenu and open the Calibration tab and
check the "Manually override automatic DPI settings" checkbox. Now measure the two black
rectangles, enter the values and click on the apply button.


Q. What are the system requirements?

A. There are no special requirements. However, the faster your CPU and the more memory,
the faster you can navigate. For example, a large pagetime (five minutes or more) will make
the responsetime of the program longer, specially when you add a lot of signals and/or
when the signals have a high samplerate.
When you open a file with a size of hundred megabytes and you choose to make the whole
recording visible on the screen, the program will load the whole file (hundred megabytes)
into memory (RAM).


Q. Which operatingsystems are supported?

A. Linux and Windows 2000/XP/Vista/7. The source can be compiled on the Mac.


Q. Which license is used for the program?

A. The GNU General Public License version 2. For more info go to Help -> About EDFbrowser.


Q. I think I found a bug. Where do I report it?

A. First check if you are using the latest version of EDFbrowser.
If the bug persists, send an email to teuniz@gmail.com


Table of Contents

















































edfbrowser_153_source/PaxHeaders.2978/load_montage_dialog.h0000644000175000001440000000013212251654530022270 xustar000000000000000030 mtime=1386699096.467032575 30 atime=1386699096.467032575 30 ctime=1386699096.467032575 edfbrowser_153_source/load_montage_dialog.h0000644000175000001440000000424512251654530022026 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef LOADMONTAGEFORM1_H #define LOADMONTAGEFORM1_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "mainwindow.h" #include "xml.h" #include "filter.h" #include "popup_messagewindow.h" #include "utc_date_time.h" #include "utils.h" #include "third_party/fidlib/fidlib.h" class UI_Mainwindow; class UI_LoadMontagewindow : public QObject { Q_OBJECT public: UI_LoadMontagewindow(QWidget *parent, char *path = NULL); UI_Mainwindow *mainwindow; private: QDialog *LoadMontageDialog; QLabel *label1; QListWidget *filelist; QPushButton *CloseButton, *LoadButton; char mtg_path[MAX_PATH_LENGTH]; void strip_types_from_label(char *); private slots: void LoadButtonClicked(); }; #endif // LOADMONTAGEFORM1_H edfbrowser_153_source/PaxHeaders.2978/spectrumanalyzer.h0000644000175000001440000000013212251654530021730 xustar000000000000000030 mtime=1386699096.468032569 30 atime=1386699096.468032569 30 ctime=1386699096.468032569 edfbrowser_153_source/spectrumanalyzer.h0000644000175000001440000000615012251654530021463 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef SPECTRUMANALYZER_H #define SPECTRUMANALYZER_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "mainwindow.h" #include "signalcurve.h" #include "fourier.h" #include "popup_messagewindow.h" #include "utils.h" #include "filter.h" #include "ravg_filter.h" #include "flywheel.h" #include "third_party/fidlib/fidlib.h" #include "third_party/kiss_fft/kiss_fftr.h" class UI_Mainwindow; class UI_FreqSpectrumWindow : public QObject { Q_OBJECT public: UI_FreqSpectrumWindow(struct signalcompblock *, char *, UI_FreqSpectrumWindow **, int, QWidget *); ~UI_FreqSpectrumWindow(); UI_Mainwindow *mainwindow; QDialog *SpectrumDialog; struct signalcompblock *signalcomp; private: QHBoxLayout *hlayout1, *hlayout2, *hlayout3, *hlayout4; QVBoxLayout *vlayout1, *vlayout2, *vlayout3; SignalCurve *curve1; QTimer *t1; QSlider *amplitudeSlider, *spanSlider, *centerSlider; QLabel *spanLabel, *centerLabel, *amplitudeLabel; QCheckBox *sqrtCheckBox, *BWCheckBox; UI_Flywheel *flywheel1; int samples, steps, spectrumdialog_is_destroyed, spectrumdialognumber, flywheel_value; volatile int busy; double samplefreq, freqstep, maxvalue, maxvalue_sqrt, *buf1, *buf2, *buf3; char *viewbuf, signallabel[512], physdimension[9]; UI_FreqSpectrumWindow **spectrumdialog; private slots: void update_curve(); void sliderMoved(int); void SpectrumDialogDestroyed(QObject *); void print_to_txt(); void update_flywheel(int); }; #endif edfbrowser_153_source/PaxHeaders.2978/signals_dialog.h0000644000175000001440000000013212251654530021277 xustar000000000000000030 mtime=1386699096.468032569 30 atime=1386699096.468032569 30 ctime=1386699096.468032569 edfbrowser_153_source/signals_dialog.h0000644000175000001440000000562112251654530021034 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef SIGNALSFORM1_H #define SIGNALSFORM1_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "global.h" #include "popup_messagewindow.h" #include "mainwindow.h" #include "colordialog.h" #include "popup_messagewindow.h" #include "utc_date_time.h" #include "special_button.h" #include "utils.h" class UI_Mainwindow; class UI_Signalswindow : public QObject { Q_OBJECT public: UI_Signalswindow(QWidget *parent); UI_Mainwindow *mainwindow; private: QDialog *SignalsDialog; QListWidget *filelist, *signallist, *compositionlist; QLabel *label1, *label2, *label3, *label4, *label5, *label6, *colorlabel; QPushButton *CloseButton, *SelectAllButton, *DisplayButton, *DisplayCompButton, *AddButton, *SubtractButton, *RemoveButton, *HelpButton; SpecialButton *ColorButton; int smp_per_record, curve_color; char physdimension[64]; double bitvalue; void strip_types_from_label(char *); private slots: void show_signals(int); void SelectAllButtonClicked(); void DisplayButtonClicked(); void DisplayCompButtonClicked(); void AddButtonClicked(); void SubtractButtonClicked(); void RemoveButtonClicked(); void ColorButtonClicked(SpecialButton *); void HelpButtonClicked(); }; #endif // SIGNALSFORM1_H edfbrowser_153_source/PaxHeaders.2978/manscan2edf.cpp0000644000175000001440000000013212251654530021034 xustar000000000000000030 mtime=1386699096.478032517 30 atime=1386699096.478032517 30 ctime=1386699096.478032517 edfbrowser_153_source/manscan2edf.cpp0000644000175000001440000012023612251654530020571 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "manscan2edf.h" #if defined(__APPLE__) || defined(__MACH__) || defined(__APPLE_CC__) #define fopeno fopen #else #define fseeko fseeko64 #define ftello ftello64 #define fopeno fopen64 #endif #define MBILINEBUFSZ 4096 #define MBIMAXEVENTS 10000 #define MBIMAXEVLEN 40 struct segment_prop_struct{ long long data_offset; int sweeps; int channels; int samplefrequency; int sec_duration; char label[MAXSIGNALS][17]; double gain[MAXSIGNALS]; int startdate_year; int startdate_month; int startdate_day; int starttime_hour; int starttime_minute; int starttime_second; double hpf; double lpf; char recorder_version[128]; char recorder_brand[128]; char datafilename[MAX_PATH_LENGTH]; long long starttime_offset; int ev_cnt; long long ev_onset[MBIMAXEVENTS]; long long ev_duration[MBIMAXEVENTS]; char ev_description[MBIMAXEVENTS][MBIMAXEVLEN + 1]; }; UI_MANSCAN2EDFwindow::UI_MANSCAN2EDFwindow(char *recent_dir, char *save_dir) { char txt_string[2048]; recent_opendir = recent_dir; recent_savedir = save_dir; myobjectDialog = new QDialog; myobjectDialog->setMinimumSize(QSize(600, 480)); myobjectDialog->setMaximumSize(QSize(600, 480)); myobjectDialog->setWindowTitle("Manscan to EDF+ converter"); myobjectDialog->setModal(TRUE); myobjectDialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); pushButton1 = new QPushButton(myobjectDialog); pushButton1->setGeometry(QRect(20, 430, 100, 26)); pushButton1->setText("Select File"); pushButton2 = new QPushButton(myobjectDialog); pushButton2->setGeometry(QRect(480, 430, 100, 26)); pushButton2->setText("Close"); textEdit1 = new QTextEdit(myobjectDialog); textEdit1->setGeometry(QRect(20, 20, 560, 380)); textEdit1->setFrameStyle(QFrame::Panel | QFrame::Sunken); textEdit1->setReadOnly(TRUE); textEdit1->setLineWrapMode(QTextEdit::NoWrap); sprintf(txt_string, "Manscan MICROAMPS binary data to EDF+ converter.\n"); textEdit1->append(txt_string); QObject::connect(pushButton1, SIGNAL(clicked()), this, SLOT(SelectFileButton())); QObject::connect(pushButton2, SIGNAL(clicked()), myobjectDialog, SLOT(close())); myobjectDialog->exec(); } void UI_MANSCAN2EDFwindow::SelectFileButton() { FILE *header_inputfile=NULL, *data_inputfile=NULL; int i, j, k, n, tmp, hdl, chns=0, sf, blocks, *buf, progress_steps, segment_cnt, n_segments=0; long long filesize, ll_tmp; char header_filename[MAX_PATH_LENGTH], txt_string[2048], edf_filename[MAX_PATH_LENGTH], data_filename[MAX_PATH_LENGTH], scratchpad[MAX_PATH_LENGTH]; double d_tmp; struct segment_prop_struct *segment_properties; union{ int one; char four[4]; } var; struct date_time_struct dtm_struct; pushButton1->setEnabled(FALSE); strcpy(header_filename, QFileDialog::getOpenFileName(0, "Select inputfile", QString::fromLocal8Bit(recent_opendir), "MBI files (*.mbi *.MBI)").toLocal8Bit().data()); if(!strcmp(header_filename, "")) { pushButton1->setEnabled(TRUE); return; } get_directory_from_path(recent_opendir, header_filename, MAX_PATH_LENGTH); header_inputfile = fopeno(header_filename, "rb"); if(header_inputfile==NULL) { snprintf(txt_string, 2048, "Can not open file %s for reading.\n", header_filename); textEdit1->append(QString::fromLocal8Bit(txt_string)); pushButton1->setEnabled(TRUE); return; } get_filename_from_path(scratchpad, header_filename, MAX_PATH_LENGTH); snprintf(txt_string, 2048, "Read file: %s", scratchpad); textEdit1->append(QString::fromLocal8Bit(txt_string)); fseeko(header_inputfile, 0LL, SEEK_END); filesize = ftello(header_inputfile); if(filesize<10) { textEdit1->append("Error, filesize is too small.\n"); fclose(header_inputfile); pushButton1->setEnabled(TRUE); return; } segment_properties = (struct segment_prop_struct *)malloc(sizeof(struct segment_prop_struct)); if(segment_properties == NULL) { textEdit1->append("Malloc error (struct segment_prop_struct)"); fclose(header_inputfile); pushButton1->setEnabled(TRUE); return; } n_segments = get_number_of_segments(header_inputfile); ////////////////// start segment processing /////////////////////////////////////////// for(segment_cnt=0; segment_cnt < n_segments; segment_cnt++) { memset(segment_properties, 0, sizeof(struct segment_prop_struct)); for(i=0; ilabel[i], "ch.%i", i + 1); segment_properties->gain[i] = 1.0; } segment_properties->samplefrequency = 256; if(get_worddatafile(segment_properties, segment_cnt, header_inputfile)) { textEdit1->append("Error, can not find or process item \"WordDataFile\".\n"); fclose(header_inputfile); free(segment_properties); pushButton1->setEnabled(TRUE); return; } if(get_channel_gain(segment_properties, segment_cnt, header_inputfile)) { textEdit1->append("Error, can not find or process item \"Channel gain\".\n"); fclose(header_inputfile); free(segment_properties); pushButton1->setEnabled(TRUE); return; } if(get_start_date(segment_properties, segment_cnt, header_inputfile)) { textEdit1->append("Error, can not find or process item \"Startdate\".\n"); fclose(header_inputfile); free(segment_properties); pushButton1->setEnabled(TRUE); return; } if(get_sample_rate(segment_properties, segment_cnt, header_inputfile)) { textEdit1->append("Error, can not find or process item \"SampleRate\".\n"); fclose(header_inputfile); free(segment_properties); pushButton1->setEnabled(TRUE); return; } if(get_filter_settings(segment_properties, segment_cnt, header_inputfile)) { textEdit1->append("Error, can not find or process item \"Filtersettings\".\n"); fclose(header_inputfile); free(segment_properties); pushButton1->setEnabled(TRUE); return; } if(get_recorder_version(segment_properties, segment_cnt, header_inputfile)) { textEdit1->append("Error, can not find or process item \"Filtersettings\".\n"); fclose(header_inputfile); free(segment_properties); pushButton1->setEnabled(TRUE); return; } if(get_starttime_offset(segment_properties, segment_cnt, header_inputfile)) { textEdit1->append("Error, can not find or process item \"Starttime offset\".\n"); fclose(header_inputfile); free(segment_properties); pushButton1->setEnabled(TRUE); return; } if(get_events(segment_properties, segment_cnt, header_inputfile)) { textEdit1->append("Error, can not find or process item \"Events\".\n"); fclose(header_inputfile); free(segment_properties); pushButton1->setEnabled(TRUE); return; } segment_properties->sec_duration = segment_properties->sweeps / segment_properties->samplefrequency; // for(i=0; iev_cnt; i++) // { // printf("%s %lli %lli\n", segment_properties->ev_description[i], segment_properties->ev_onset[i], segment_properties->ev_duration[i]); // } // // for(i=0; ichannels; i++) // { // printf("%s %.10f\n", segment_properties->label[i], segment_properties->gain[i]); // } // printf("data_offset is %lli sweeps is %i datafileheader_filename is %s\n", segment_properties->data_offset, segment_properties->sweeps, segment_properties->datafilename); // // printf("startdate_day is %i startdate_month is %i startdate_year is %i\n", segment_properties->startdate_day, segment_properties->startdate_month, segment_properties->startdate_year); // // printf("starttime is: %02i:%02i:%02i starttime offset is: %lli\n", segment_properties->starttime_hour, segment_properties->starttime_minute, segment_properties->starttime_second, segment_properties->starttime_offset); // // printf("samplerate is: %i hpf is %f lpf is %f\n", segment_properties->samplefrequency, segment_properties->hpf, segment_properties->lpf); // // printf("recorder version: %s recorder brand: %s\n", segment_properties->recorder_version, segment_properties->recorder_brand); // // printf("recording duration: %i seconds\n", segment_properties->sec_duration); chns = segment_properties->channels; sf = segment_properties->samplefrequency; blocks = segment_properties->sec_duration; if(blocks < 1) { snprintf(txt_string, 2048, "Skipping segment %i because it's shorter dan one second.", segment_cnt + 1); textEdit1->append(txt_string); continue; } buf = (int *)malloc(sf * chns * sizeof(int)); if(buf == NULL) { textEdit1->append("Malloc() error (buf)\n"); fclose(header_inputfile); free(segment_properties); pushButton1->setEnabled(TRUE); return; } strcpy(edf_filename, header_filename); remove_extension_from_filename(edf_filename); if(n_segments > 1) { sprintf(edf_filename + strlen(edf_filename), "_%02i", segment_cnt + 1); } strcat(edf_filename, ".edf"); get_directory_from_path(data_filename, header_filename, MAX_PATH_LENGTH - 1); strcat(data_filename, "/"); strcat(data_filename, segment_properties->datafilename); data_inputfile = fopeno(data_filename, "rb"); if(data_inputfile==NULL) { snprintf(txt_string, 2048, "Can not open file %s for reading.\n", data_filename); textEdit1->append(QString::fromLocal8Bit(txt_string)); fclose(header_inputfile); free(buf); free(segment_properties); pushButton1->setEnabled(TRUE); return; } fseeko(data_inputfile, 0LL, SEEK_END); filesize = ftello(data_inputfile); if(filesize < (segment_properties->data_offset + (chns * 2))) { textEdit1->append("Error, filesize is too small.\n"); fclose(header_inputfile); fclose(data_inputfile); free(buf); free(segment_properties); pushButton1->setEnabled(TRUE); return; } n = (filesize - segment_properties->data_offset) / (chns * 2); if(n < segment_properties->sweeps) { segment_properties->sweeps = n; snprintf(txt_string, 2048, "Warning: samples in datafile are less than in headerfile."); textEdit1->append(txt_string); } get_filename_from_path(scratchpad, edf_filename, MAX_PATH_LENGTH - 1); snprintf(txt_string, 2048, "Convert a segment to %s ...", scratchpad); textEdit1->append(txt_string); hdl = edfopen_file_writeonly(edf_filename, EDFLIB_FILETYPE_EDFPLUS, chns); if(hdl<0) { snprintf(txt_string, 2048, "Can not open file %s for writing.\n", edf_filename); textEdit1->append(QString::fromLocal8Bit(txt_string)); fclose(header_inputfile); fclose(data_inputfile); free(buf); free(segment_properties); pushButton1->setEnabled(TRUE); return; } for(i=0; iappend("Error: edf_set_samplefrequency()\n"); fclose(header_inputfile); fclose(data_inputfile); edfclose_file(hdl); free(buf); free(segment_properties); pushButton1->setEnabled(TRUE); return; } } for(i=0; iappend("Error: edf_set_digital_minimum()\n"); fclose(header_inputfile); fclose(data_inputfile); edfclose_file(hdl); free(buf); free(segment_properties); pushButton1->setEnabled(TRUE); return; } } for(i=0; iappend("Error: edf_set_digital_maximum()\n"); fclose(header_inputfile); fclose(data_inputfile); edfclose_file(hdl); free(buf); free(segment_properties); pushButton1->setEnabled(TRUE); return; } } for(i=0; ilabel[i])) { textEdit1->append("Error: edf_set_label()\n"); fclose(header_inputfile); fclose(data_inputfile); edfclose_file(hdl); free(buf); free(segment_properties); pushButton1->setEnabled(TRUE); return; } } for(i=0; igain[i] > 0.999) { d_tmp = 32767.0 / segment_properties->gain[i]; strcpy(scratchpad, "uV"); } else { d_tmp = 32.767 / segment_properties->gain[i]; strcpy(scratchpad, "mV"); } if(edf_set_physical_dimension(hdl, i, scratchpad)) { textEdit1->append("Error: edf_set_physical_dimension()\n"); fclose(header_inputfile); fclose(data_inputfile); edfclose_file(hdl); free(buf); free(segment_properties); pushButton1->setEnabled(TRUE); return; } if(edf_set_physical_maximum(hdl, i, d_tmp)) { textEdit1->append("Error: edf_set_physical_maximum()\n"); fclose(header_inputfile); fclose(data_inputfile); edfclose_file(hdl); free(buf); free(segment_properties); pushButton1->setEnabled(TRUE); return; } if(edf_set_physical_minimum(hdl, i, -(d_tmp))) { textEdit1->append("Error: edf_set_physical_minimum()\n"); fclose(header_inputfile); fclose(data_inputfile); edfclose_file(hdl); free(buf); free(segment_properties); pushButton1->setEnabled(TRUE); return; } } dtm_struct.year = segment_properties->startdate_year; dtm_struct.month = segment_properties->startdate_month; dtm_struct.day = segment_properties->startdate_day; dtm_struct.hour = segment_properties->starttime_hour; dtm_struct.minute = segment_properties->starttime_minute; dtm_struct.second = segment_properties->starttime_second; date_time_to_utc(&ll_tmp, dtm_struct); ll_tmp += segment_properties->starttime_offset / TIME_DIMENSION; utc_to_date_time(ll_tmp, &dtm_struct); if(edf_set_startdatetime(hdl, dtm_struct.year, dtm_struct.month, dtm_struct.day, dtm_struct.hour, dtm_struct.minute, dtm_struct.second)) { textEdit1->append("Error: edf_set_startdatetime()\n"); fclose(header_inputfile); fclose(data_inputfile); edfclose_file(hdl); free(buf); free(segment_properties); pushButton1->setEnabled(TRUE); return; } if(edf_set_equipment(hdl, segment_properties->recorder_brand)) { textEdit1->append("Error: edf_set_equipment()\n"); fclose(header_inputfile); fclose(data_inputfile); edfclose_file(hdl); free(buf); free(segment_properties); pushButton1->setEnabled(TRUE); return; } if(edf_set_recording_additional(hdl, segment_properties->recorder_version)) { textEdit1->append("Error: edf_set_recording_additional()\n"); fclose(header_inputfile); fclose(data_inputfile); edfclose_file(hdl); free(buf); free(segment_properties); pushButton1->setEnabled(TRUE); return; } scratchpad[0] = 0; if(segment_properties->hpf > 0.0001) { sprintf(scratchpad + strlen(scratchpad), "HP:%f", segment_properties->hpf); remove_trailing_zeros(scratchpad); strcat(scratchpad, "Hz "); } if(segment_properties->lpf > 0.0001) { sprintf(scratchpad + strlen(scratchpad), "LP:%f", segment_properties->lpf); remove_trailing_zeros(scratchpad); strcat(scratchpad, "Hz "); } for(i=0; iappend("Error: edf_set_prefilter()\n"); fclose(header_inputfile); fclose(data_inputfile); edfclose_file(hdl); free(buf); free(segment_properties); pushButton1->setEnabled(TRUE); return; } } ////////////////// start conversion /////////////////////////////////////////// QProgressDialog progress("Converting a segment...", "Abort", 0, blocks); progress.setWindowModality(Qt::WindowModal); progress.setMinimumDuration(200); progress_steps = blocks / 100; if(progress_steps < 1) { progress_steps = 1; } fseeko(data_inputfile, segment_properties->data_offset, SEEK_SET); for(i=0; iprocessEvents(); if(progress.wasCanceled() == TRUE) { textEdit1->append("Conversion aborted by user.\n"); fclose(header_inputfile); fclose(data_inputfile); edfclose_file(hdl); free(buf); free(segment_properties); pushButton1->setEnabled(TRUE); return; } } for(j=0; jappend("A read error occurred during conversion.\n"); fclose(header_inputfile); fclose(data_inputfile); edfclose_file(hdl); free(buf); free(segment_properties); pushButton1->setEnabled(TRUE); return; } var.four[3] = tmp; buf[(k * sf) + j] = (var.one >> 16); } } if(edf_blockwrite_digital_samples(hdl, buf)) { progress.reset(); textEdit1->append("A write error occurred during conversion.\n"); fclose(header_inputfile); fclose(data_inputfile); edfclose_file(hdl); free(buf); free(segment_properties); pushButton1->setEnabled(TRUE); return; } } ////////////////// end of conversion /////////////////////////////////////////// if(edfwrite_annotation_latin1(hdl, 0LL, -1LL, "Recording starts")) { textEdit1->append("Error: edfwrite_annotation_latin1()\n"); fclose(header_inputfile); fclose(data_inputfile); edfclose_file(hdl); free(buf); free(segment_properties); pushButton1->setEnabled(TRUE); return; } for(i=0; iev_cnt; i++) { if(edfwrite_annotation_latin1(hdl, segment_properties->ev_onset[i], segment_properties->ev_duration[i], segment_properties->ev_description[i])) { textEdit1->append("Error: edfwrite_annotation_latin1()\n"); fclose(header_inputfile); fclose(data_inputfile); edfclose_file(hdl); free(buf); free(segment_properties); pushButton1->setEnabled(TRUE); return; } } if(edfwrite_annotation_latin1(hdl, (long long)blocks * 10000LL, -1LL, "Recording ends")) { textEdit1->append("Error: edfwrite_annotation_latin1()\n"); fclose(header_inputfile); fclose(data_inputfile); edfclose_file(hdl); free(buf); free(segment_properties); pushButton1->setEnabled(TRUE); return; } fclose(data_inputfile); edfclose_file(hdl); free(buf); textEdit1->append("... conversion of segment done."); } ////////////////// end of segment processing /////////////////////////////////////////// fclose(header_inputfile); free(segment_properties); textEdit1->append("Ready.\n"); pushButton1->setEnabled(TRUE); } int UI_MANSCAN2EDFwindow::get_events(struct segment_prop_struct *segprop, int segment, FILE *inputfile) { int i, order=0, startsmpl, durationsmpl, ev_cnt=0, segment_cnt=0; char linebuf[MBILINEBUFSZ], annot_descr[MBIMAXEVLEN + 1]; long long onset, duration, sf; sf = segprop->samplefrequency; rewind(inputfile); while(segment_cnt != segment) { if(fgetline(linebuf, MBILINEBUFSZ, inputfile) == NULL) { return(0); } strntolower(linebuf, 11); if(!(strncmp(linebuf, "datatypeid ", 11))) { segment_cnt++; } } while(1) { if(fgetline(linebuf, MBILINEBUFSZ, inputfile) == NULL) { return(0); } strntolower(linebuf, 11); if(!(strncmp(linebuf, "datatypeid ", 11))) { return(0); } strntolower(linebuf, 33); if((!(strncmp(linebuf, "event beginsample durationsamples", 33))) || (!(strncmp(linebuf, "event durationsamples beginsample", 33)))) { if(!(strncmp(linebuf, "event beginsample durationsamples", 33))) { order = 1; } else { order = 0; } if(fgetline(linebuf, MBILINEBUFSZ, inputfile) == NULL) { return(0); } strntolower(linebuf, 22); if(!(strncmp(linebuf, "string integer integer", 22))) { for(i=0; ; i++) { if(fgetline(linebuf, MBILINEBUFSZ, inputfile) == NULL) { return(-1); } if(strlen(linebuf) == 0) { break; } if(strlen(linebuf) < 5) { return(-1); } if(order) { if(sscanf(linebuf, "%40s %i %i", annot_descr, &startsmpl, &durationsmpl) != 3) { return(-1); } } else { if(sscanf(linebuf, "%40s %i %i", annot_descr, &durationsmpl, &startsmpl) != 3) { return(-1); } } if(startsmpl < 0) { continue; } onset = ((long long)startsmpl * 10000LL) / sf; if(durationsmpl < 2) { duration = -1LL; } else { duration = ((long long)durationsmpl * 10000LL) / sf; } strcpy(segprop->ev_description[ev_cnt], annot_descr); segprop->ev_onset[ev_cnt] = onset; segprop->ev_duration[ev_cnt] = duration; segprop->ev_cnt = ++ev_cnt; if(ev_cnt >= MBIMAXEVENTS) { return(0); } } } else { continue; } } } return(0); } int UI_MANSCAN2EDFwindow::get_starttime_offset(struct segment_prop_struct *segprop, int segment, FILE *inputfile) { int segment_cnt=0; char linebuf[MBILINEBUFSZ]; long long time; rewind(inputfile); while(segment_cnt != segment) { if(fgetline(linebuf, MBILINEBUFSZ, inputfile) == NULL) { return(0); } strntolower(linebuf, 11); if(!(strncmp(linebuf, "datatypeid ", 11))) { segment_cnt++; } } while(1) { if(fgetline(linebuf, MBILINEBUFSZ, inputfile) == NULL) { return(0); } strntolower(linebuf, 11); if(!(strncmp(linebuf, "datatypeid ", 11))) { return(0); } strntolower(linebuf, 24); if(!(strncmp(linebuf, "offsetdisplayexperiment ", 24))) { break; } } if(strlen(linebuf) < 25) { return(-1); } time = get_long_time(linebuf + 24); segprop->starttime_offset = time; return(0); } int UI_MANSCAN2EDFwindow::get_recorder_version(struct segment_prop_struct *segprop, int segment, FILE *inputfile) { int segment_cnt=0; char linebuf[MBILINEBUFSZ]; rewind(inputfile); while(segment_cnt != segment) { if(fgetline(linebuf, MBILINEBUFSZ, inputfile) == NULL) { return(0); } strntolower(linebuf, 11); if(!(strncmp(linebuf, "datatypeid ", 11))) { segment_cnt++; } } while(1) { if(fgetline(linebuf, MBILINEBUFSZ, inputfile) == NULL) { return(0); } strntolower(linebuf, 11); if(!(strncmp(linebuf, "datatypeid ", 11))) { return(0); } strntolower(linebuf, 25); if(!(strncmp(linebuf, "comment recorder version ", 25))) { break; } } if(strlen(linebuf) < 26) { return(-1); } strncpy(segprop->recorder_version, linebuf + 25, 100); return(0); } int UI_MANSCAN2EDFwindow::get_filter_settings(struct segment_prop_struct *segprop, int segment, FILE *inputfile) { int segment_cnt=0; char linebuf[MBILINEBUFSZ], *chrpntr; double lpf, hpf; rewind(inputfile); while(segment_cnt != segment) { if(fgetline(linebuf, MBILINEBUFSZ, inputfile) == NULL) { return(0); } strntolower(linebuf, 11); if(!(strncmp(linebuf, "datatypeid ", 11))) { segment_cnt++; } } while(1) { if(fgetline(linebuf, MBILINEBUFSZ, inputfile) == NULL) { return(0); } strntolower(linebuf, 11); if(!(strncmp(linebuf, "datatypeid ", 11))) { return(0); } strntolower(linebuf, 18); if(!(strncmp(linebuf, "comment microamps ", 18))) { break; } } if(strlen(linebuf) < 53) { return(-1); } strncpy(segprop->recorder_brand, linebuf + 8, 13); chrpntr = linebuf + 18; chrpntr = strchr(chrpntr, ' '); if(chrpntr == NULL) { return(-1); } chrpntr++; if(strncmp(chrpntr, "highpass ", 9)) { return(-1); } chrpntr = strchr(chrpntr, ' '); if(chrpntr == NULL) { return(-1); } chrpntr++; hpf = atof(chrpntr); if((hpf < 0.000001) || (hpf > 100000.0)) { return(-1); } chrpntr = strchr(chrpntr, ' '); if(chrpntr == NULL) { return(-1); } chrpntr++; if(strncmp(chrpntr, "hz, ", 4)) { return(-1); } chrpntr = strchr(chrpntr, ' '); if(chrpntr == NULL) { return(-1); } chrpntr++; if(strncmp(chrpntr, "lowpass ", 8)) { return(-1); } chrpntr++; chrpntr = strchr(chrpntr, ' '); if(chrpntr == NULL) { return(-1); } chrpntr++; lpf = atof(chrpntr); if((lpf < 0.000001) || (lpf > 100000.0)) { return(-1); } chrpntr = strchr(chrpntr, ' '); if(chrpntr == NULL) { return(-1); } chrpntr++; if(strncmp(chrpntr, "hz", 2)) { return(-1); } segprop->hpf = hpf; segprop->lpf = lpf; return(0); } int UI_MANSCAN2EDFwindow::get_sample_rate(struct segment_prop_struct *segprop, int segment, FILE *inputfile) { int sf, segment_cnt=0; char linebuf[MBILINEBUFSZ]; double d_tmp; rewind(inputfile); while(segment_cnt != segment) { if(fgetline(linebuf, MBILINEBUFSZ, inputfile) == NULL) { return(0); } strntolower(linebuf, 11); if(!(strncmp(linebuf, "datatypeid ", 11))) { segment_cnt++; } } while(1) { if(fgetline(linebuf, MBILINEBUFSZ, inputfile) == NULL) { return(0); } strntolower(linebuf, 11); if(!(strncmp(linebuf, "datatypeid ", 11))) { return(0); } strntolower(linebuf, 11); if(!(strncmp(linebuf, "samplerate ", 11))) { if(strlen(linebuf) < 12) { return(-1); } break; } strntolower(linebuf, 16); if(!(strncmp(linebuf, "sampletodisplay ", 16))) { if(strlen(linebuf) < 17) { return(-1); } break; } } if(!(strncmp(linebuf, "samplerate ", 11))) { sf = atoi(linebuf + 11); } else { d_tmp = atof(linebuf + 16); if(d_tmp < 0.00001) { return(-1); } d_tmp = 1.0 / d_tmp; sf = d_tmp; d_tmp -= sf; if(d_tmp > 0.5) { sf++; } } if((sf < 1) || (sf > 100000)) { return(-1); } segprop->samplefrequency = sf; return(0); } int UI_MANSCAN2EDFwindow::get_start_date(struct segment_prop_struct *segprop, int segment, FILE *inputfile) { int p, p2, len, segment_cnt=0, starttime_second, starttime_minute, starttime_hour, startdate_day, startdate_month, startdate_year; char linebuf[MBILINEBUFSZ]; rewind(inputfile); while(segment_cnt != segment) { if(fgetline(linebuf, MBILINEBUFSZ, inputfile) == NULL) { return(-1); } strntolower(linebuf, 11); if(!(strncmp(linebuf, "datatypeid ", 11))) { segment_cnt++; } } while(1) { if(fgetline(linebuf, MBILINEBUFSZ, inputfile) == NULL) { return(-1); } strntolower(linebuf, 11); if(!(strncmp(linebuf, "datatypeid ", 11))) { return(-1); } strntolower(linebuf, 15); if(!(strncmp(linebuf, "experimenttime ", 15))) { break; } } len = strlen(linebuf); if(len < 23) { return(-1); } p = 15; if(((linebuf[p+2] != '/') || (linebuf[p+5] != '/')) && ((linebuf[p+2] != '-') || (linebuf[p+5] != '-'))) { return(-1); } if((linebuf[p] < '0') || (linebuf[p] > '9') || (linebuf[p+1] < '0') || (linebuf[p+1] > '9') || (linebuf[p+3] < '0') || (linebuf[p+3] > '9') || (linebuf[p+4] < '0') || (linebuf[p+4] > '9') || (linebuf[p+6] < '0') || (linebuf[p+6] > '9') || (linebuf[p+7] < '0') || (linebuf[p+7] > '9')) { return(-1); } if((len - p) > 9) { if((linebuf[p+8] >= '0') && (linebuf[p+8] <= '9') && (linebuf[p+9] >= '0') && (linebuf[p+9] <= '9')) { startdate_year = atoi(linebuf + p + 6); p2 = p + 10; } else { startdate_year = atoi(linebuf + p + 6); if(startdate_year >= 70) { startdate_year += 1900; } else { startdate_year += 2000; } p2 = p + 8; } } else { startdate_year = atoi(linebuf + p + 6); if(startdate_year >= 70) { startdate_year += 1900; } else { startdate_year += 2000; } p2 = p + 8; } startdate_day = atoi(linebuf + p + 3); startdate_month = atoi(linebuf + p); if((startdate_day < 1) || (startdate_day > 31) || (startdate_month < 1) || (startdate_month > 12)) { return(-1); } segprop->startdate_day = startdate_day; segprop->startdate_month = startdate_month; segprop->startdate_year = startdate_year; p = p2; if(linebuf[p] == ' ') { p++; if((len - p) > 7) { if((linebuf[p+2] == ':') && (linebuf[p+5] == ':')) { if((linebuf[p] < '0') || (linebuf[p] > '9') || (linebuf[p+1] < '0') || (linebuf[p+1] > '9') || (linebuf[p+3] < '0') || (linebuf[p+3] > '9') || (linebuf[p+4] < '0') || (linebuf[p+4] > '9') || (linebuf[p+6] < '0') || (linebuf[p+6] > '9') || (linebuf[p+7] < '0') || (linebuf[p+7] > '9')) { return(-1); } starttime_hour = atoi(linebuf + p); starttime_minute = atoi(linebuf + p + 3); starttime_second = atoi(linebuf + p + 6); if((starttime_hour < 0) || (starttime_hour > 23)) { starttime_hour = 0; starttime_minute = 0; starttime_second = 0; return(-1); } if((starttime_minute < 0) || (starttime_minute > 59)) { starttime_hour = 0; starttime_minute = 0; starttime_second = 0; return(-1); } if((starttime_second < 0) || (starttime_second > 59)) { starttime_hour = 0; starttime_minute = 0; starttime_second = 0; return(-1); } segprop->starttime_hour = starttime_hour; segprop->starttime_minute = starttime_minute; segprop->starttime_second = starttime_second; } } } return(0); } int UI_MANSCAN2EDFwindow::get_channel_gain(struct segment_prop_struct *segprop, int segment, FILE *inputfile) { int i, j, len, segment_cnt=0, channels, column; char linebuf[MBILINEBUFSZ], *chrpntr, label[17]; double gain; channels = segprop->channels; if((channels < 1) || (channels > MAXSIGNALS)) { return(-1); } rewind(inputfile); while(segment_cnt != segment) { if(fgetline(linebuf, MBILINEBUFSZ, inputfile) == NULL) { return(-1); } strntolower(linebuf, 11); if(!(strncmp(linebuf, "datatypeid ", 11))) { segment_cnt++; } } while(1) { if(fgetline(linebuf, MBILINEBUFSZ, inputfile) == NULL) { return(-1); } strntolower(linebuf, 256); if(!(strncmp(linebuf, "datatypeid ", 11))) { return(-1); } if(!(strncmp(linebuf, "channel ", 8))) { if(strstr(linebuf, "unitdisplaytofile") != NULL) { break; } } } chrpntr = linebuf; for(column=1; ; column++) { chrpntr = strchr(chrpntr, ' ') + 1; if((chrpntr == NULL) || (strlen(chrpntr) < 17)) { return(-1); } if(!(strncmp(chrpntr, "unitdisplaytofile", 17))) { break; } } for(i=0; i 16) { len = 16; } strncpy(label, linebuf, len); label[len] = 0; chrpntr++; for(j=1; j= (linebuf + strlen(linebuf))) { return(-1); } gain = atof(chrpntr); for(j=0; jlabel[j]))) { segprop->gain[j] = gain; break; } } } return(0); } int UI_MANSCAN2EDFwindow::get_worddatafile(struct segment_prop_struct *segprop, int segment, FILE *inputfile) { int i, j, p, len, tmp, segment_cnt=0, channels; char linebuf[MBILINEBUFSZ], scratchpad[256]; rewind(inputfile); while(segment_cnt != segment) { if(fgetline(linebuf, MBILINEBUFSZ, inputfile) == NULL) { return(-1); } strntolower(linebuf, 11); if(!(strncmp(linebuf, "datatypeid ", 11))) { segment_cnt++; } } while(1) { if(fgetline(linebuf, MBILINEBUFSZ, inputfile) == NULL) { return(-1); } strntolower(linebuf, 11); if(!(strncmp(linebuf, "datatypeid ", 11))) { return(-1); } strntolower(linebuf, 12); if(!(strncmp(linebuf, "worddatafile", 12))) { break; } } if(fgetline(linebuf, MBILINEBUFSZ, inputfile) == NULL) { return(-1); } channels = 0; j = 0; for(i=0; ; i++) { if(linebuf[i] == 0) { if(j > 0) { if(j > 16) { j = 16; } segprop->label[channels][j] = 0; channels++; } break; } if(linebuf[i] == ' ') { if(j > 0) { if(j > 16) { j = 16; } segprop->label[channels][j] = 0; channels++; } j = 0; continue; } if(channels >= MAXSIGNALS) { return(-1); } if(j < 16) { segprop->label[channels][j++] = linebuf[i]; } } if(channels < 1) { return(-1); } segprop->channels = channels; if(fgetline(linebuf, MBILINEBUFSZ, inputfile) == NULL) // data offset, sweeps, filename { return(-1); } if(strlen(linebuf) < 9) { return(-1); } for(len=0; ; len++) { if((linebuf[len] == ' ') || (linebuf[len] == 0)) { break; } } if((len < 1) || (len > 255)) { return(-1); } strncpy(scratchpad, linebuf, len); scratchpad[len] = 0; tmp = atoi(scratchpad); // field 1 for(p=len; ; p++) { if((linebuf[p] != ' ') || (linebuf[p] == 0)) { break; } } for(len=0; ; len++) { if((linebuf[p+len] == ' ') || (linebuf[p+len] == 0)) { break; } } if((len < 1) || (len > 255)) { return(-1); } strncpy(scratchpad, linebuf + p, len); scratchpad[len] = 0; segprop->data_offset = atoi(scratchpad); // field 2 segprop->data_offset <<= 32; segprop->data_offset += tmp; for(p+=len; ; p++) { if((linebuf[p] != ' ') || (linebuf[p] == 0)) { break; } } for(len=0; ; len++) { if((linebuf[p+len] == ' ') || (linebuf[p+len] == 0)) { break; } } if((len < 1) || (len > 255)) { return(-1); } strncpy(scratchpad, linebuf + p, len); scratchpad[len] = 0; segprop->sweeps = atoi(scratchpad); // field 3 for(p+=len; ; p++) { if((linebuf[p] != ' ') || (linebuf[p] == 0)) { break; } } for(len=0; ; len++) { if((linebuf[p+len] == ' ') || (linebuf[p+len] == 0)) { break; } } if((len < 3) || (len > 255)) { return(-1); } strncpy(scratchpad, linebuf + p, len); scratchpad[len] = 0; strcpy(segprop->datafilename, scratchpad); // field 4 return(0); } int UI_MANSCAN2EDFwindow::get_number_of_segments(FILE *inputfile) { int segment_cnt=1; char linebuf[MBILINEBUFSZ]; rewind(inputfile); while(1) { if(fgetline(linebuf, MBILINEBUFSZ, inputfile) == NULL) { break; } strntolower(linebuf, 11); if(!(strncmp(linebuf, "datatypeid ", 11))) { segment_cnt++; } } return(segment_cnt); } char * UI_MANSCAN2EDFwindow::fgetline(char *s, int size, FILE *stream) { int i, j, n, spc1=0, spc2=0; char *result; result = fgets(s, size, stream); if(result == NULL) { return(result); } for(i=0; ; i++) { if(s[i] == 0) { break; } if(s[i] == '\t') { s[i] = ' '; } if((s[i] == '\n') || (s[i] == '\r')) { s[i] = 0; break; } } remove_leading_spaces(s); for(i=0; ; i++) { if(s[i] == ' ') { if((spc1 == 0) && (spc2 == 0)) { spc1 = i; } spc2 = i; } else { if(spc1 != spc2) { if(s[i] == 0) { s[spc1] = 0; return(result); } n = spc2 - spc1; for(j=spc1; ; j++) { s[j] = s[j+n]; if(s[j] == 0) { break; } } } spc1 = 0; spc2 = 0; } if(s[i] == 0) { break; } } return(result); } long long UI_MANSCAN2EDFwindow::get_long_time(const char *str) { int i, j=0, len=0, hasdot=0, dotposition=0, decimals=0; long long value=0LL, radix, sign=1LL; for(radix = TIME_DIMENSION; radix > 1LL; radix /=10) { decimals++; } if(str[0] == '+') { str++; } else { if(str[0] == '-') { sign = -1LL; str++; } } for(i=0; ; i++) { if(((str[i]<'0') || (str[i]>'9')) && (str[i]!='.')) { len = i; break; } if(str[i]=='.') { if(hasdot) { len = i; break; } hasdot = 1; dotposition = i; } else { if(hasdot) { if(++j > decimals) { len = i; break; } } } } if(hasdot) { radix = TIME_DIMENSION; for(i=dotposition-1; i>=0; i--) { value += ((long long)(str[i] - 48)) * radix; radix *= 10; } radix = TIME_DIMENSION / 10; for(i=dotposition+1; i=0; i--) { value += ((long long)(str[i] - 48)) * radix; radix *= 10; } } return(value * sign); } edfbrowser_153_source/PaxHeaders.2978/averager_dialog.cpp0000644000175000001440000000013212251654530021766 xustar000000000000000030 mtime=1386699096.477032522 30 atime=1386699096.477032522 30 ctime=1386699096.477032522 edfbrowser_153_source/averager_dialog.cpp0000644000175000001440000004237212251654530021527 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2011, 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #include "averager_dialog.h" UI_AveragerWindow::UI_AveragerWindow(QWidget *w_parent, int annot_nr) { int i, n; long long recording_duration; struct annotationblock *annot; mainwindow = (UI_Mainwindow *)w_parent; averager_dialog = new QDialog(w_parent); averager_dialog->setMinimumSize(QSize(600, 400)); averager_dialog->setMaximumSize(QSize(600, 400)); averager_dialog->setWindowTitle("Average waveforms"); averager_dialog->setModal(TRUE); averager_dialog->setAttribute(Qt::WA_DeleteOnClose, TRUE); annotLabel = new QLabel(averager_dialog); annotLabel->setGeometry(20, 20, 100, 25); annotLabel->setText("Use annotation:"); annotNameLabel = new QLabel(averager_dialog); annotNameLabel->setGeometry(130, 20, 200, 25); signalLabel = new QLabel(averager_dialog); signalLabel->setGeometry(340, 20, 100, 25); signalLabel->setText("Select signal(s):"); list = new QListWidget(averager_dialog); list->setGeometry(450, 20, 130, 360); list->setSelectionBehavior(QAbstractItemView::SelectRows); list->setSelectionMode(QAbstractItemView::ExtendedSelection); time1.setHMS(0, 0, 0, 0); recording_duration = (mainwindow->edfheaderlist[0]->datarecords * mainwindow->edfheaderlist[0]->long_data_record_duration) / TIME_DIMENSION; time2.setHMS((recording_duration / 3600) % 24, (recording_duration % 3600) / 60, recording_duration % 60, 0); time1Label = new QLabel(averager_dialog); time1Label->setGeometry(20, 65, 100, 25); time1Label->setText("From (hh:mm:ss)"); timeEdit1 = new QTimeEdit(averager_dialog); timeEdit1->setGeometry(130, 65, 110, 25); timeEdit1->setDisplayFormat("hh:mm:ss.zzz"); timeEdit1->setMinimumTime(QTime(0, 0, 0, 0)); timeEdit1->setMaximumTime(time2); time2Label = new QLabel(averager_dialog); time2Label->setGeometry(20, 110, 100, 25); time2Label->setText("To (hh:mm:ss)"); timeEdit2 = new QTimeEdit(averager_dialog); timeEdit2->setGeometry(130, 110, 110, 25); timeEdit2->setDisplayFormat("hh:mm:ss.zzz"); timeEdit2->setMinimumTime(QTime(0, 0, 0, 0)); timeEdit2->setMaximumTime(time2); timeEdit2->setTime(time2); ratioLabel = new QLabel(averager_dialog); ratioLabel->setGeometry(20, 155, 100, 75); ratioLabel->setText("Ratio of time\n" "before and after\n" "trigger:"); ratioBox = new QComboBox(averager_dialog); ratioBox->setGeometry(130, 180, 100, 25); ratioBox->addItem("10 / 90"); ratioBox->addItem("25 / 75"); ratioBox->addItem("50 / 50"); ratioBox->setCurrentIndex(mainwindow->average_ratio); bufsizeLabel = new QLabel(averager_dialog); bufsizeLabel->setGeometry(20, 250, 100, 25); bufsizeLabel->setText("Average period:"); avg_periodspinbox = new QDoubleSpinBox(averager_dialog); avg_periodspinbox->setGeometry(130, 250, 100, 25); avg_periodspinbox->setDecimals(3); avg_periodspinbox->setRange(0.01, 300.0); avg_periodspinbox->setSuffix(" sec"); avg_periodspinbox->setValue(mainwindow->average_period); CloseButton = new QPushButton(averager_dialog); CloseButton->setGeometry(20, 355, 100, 25); CloseButton->setText("Cancel"); StartButton = new QPushButton(averager_dialog); StartButton->setGeometry(310, 355, 100, 25); StartButton->setText("Start"); for(i=0; isignalcomps; i++) { if(mainwindow->signalcomp[i]->alias[0] != 0) { new QListWidgetItem(mainwindow->signalcomp[i]->alias, list); } else { new QListWidgetItem(mainwindow->signalcomp[i]->signallabel, list); } } list->setCurrentRow(0, QItemSelectionModel::Select); annot = mainwindow->annotationlist[0]; n = annot_nr; while(n) { annot = annot->next_annotation; n--; } strcpy(annot_str, annot->annotation); remove_trailing_spaces(annot_str); annotNameLabel->setText(annot_str); QObject::connect(CloseButton, SIGNAL(clicked()), averager_dialog, SLOT(close())); QObject::connect(StartButton, SIGNAL(clicked()), this, SLOT(startButtonClicked())); averager_dialog->exec(); } void UI_AveragerWindow::startButtonClicked() { int i, j, n, avg_cnt=0, samples_on_screen, trigger_position_ratio=4, dialoglistnumber, itemCnt, progress_steps; char str[MAX_ANNOTATION_LEN + 1], scratchpad[1024]; double avg_max_value, avg_min_value; long long backup_viewtime, backup_timescale, l_time1, l_time2; struct annotationblock *annot; QList itemList; mainwindow->average_period = avg_periodspinbox->value(); mainwindow->average_ratio = ratioBox->currentIndex(); itemList = list->selectedItems(); itemCnt = itemList.size(); if(itemCnt < 1) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "You have to select at least one signal."); messagewindow.exec(); return; } if(itemCnt > MAXAVERAGECURVEDIALOGS) { sprintf(scratchpad,"You can not select more than %i signals.", MAXAVERAGECURVEDIALOGS); QMessageBox messagewindow(QMessageBox::Critical, "Error", scratchpad); messagewindow.exec(); return; } time1 = timeEdit1->time(); time2 = timeEdit2->time(); if(time2.operator<=(time1) == TRUE) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Starttime is higher or equal to stoptime."); messagewindow.exec(); return; } l_time1 = (((time1.hour() * 3600) + (time1.minute() * 60) + (time1.second())) * TIME_DIMENSION) + (time1.msec() * TIME_DIMENSION / 1000LL); l_time2 = (((time2.hour() * 3600) + (time2.minute() * 60) + (time2.second())) * TIME_DIMENSION) + (time2.msec() * TIME_DIMENSION / 1000LL); n = ratioBox->currentIndex(); switch(n) { case 0 : trigger_position_ratio = 10; break; case 1 : trigger_position_ratio = 4; break; case 2 : trigger_position_ratio = 2; break; } backup_viewtime = mainwindow->edfheaderlist[0]->viewtime; backup_timescale = mainwindow->pagetime; mainwindow->pagetime = avg_periodspinbox->value() * TIME_DIMENSION; mainwindow->setup_viewbuf(); mainwindow->signal_averaging_active = 1; n = edfplus_annotation_count(&mainwindow->annotationlist[0]); avg_cnt = 0; for(i=0; iannotationlist[0], i); if(((annot->onset - mainwindow->edfheaderlist[0]->starttime_offset) >= l_time1) && ((annot->onset - mainwindow->edfheaderlist[0]->starttime_offset) <= l_time2)) { strcpy(str, annot->annotation); remove_trailing_spaces(str); if(!strcmp(str, annot_str)) { avg_cnt++; } } } QProgressDialog progress("Averaging ...", "Abort", 0, avg_cnt, averager_dialog); progress.setWindowModality(Qt::WindowModal); progress.setMinimumDuration(200); progress_steps = avg_cnt / 100; if(progress_steps < 1) { progress_steps = 1; } for(j=0; javeragecurvedialog[i] == NULL) { dialoglistnumber = i; break; } } if(i >= MAXAVERAGECURVEDIALOGS) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Too many \"Average\" windows are open.\nClose some first."); messagewindow.exec(); mainwindow->edfheaderlist[0]->viewtime = backup_viewtime; mainwindow->pagetime = backup_timescale; mainwindow->signal_averaging_active = 0; mainwindow->setup_viewbuf(); return; } signal_nr = list->row(itemList.at(j)); if(mainwindow->signalcomp[signal_nr]->samples_on_screen > 2147483646LL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Too many samples in buf."); messagewindow.exec(); mainwindow->edfheaderlist[0]->viewtime = backup_viewtime; mainwindow->pagetime = backup_timescale; mainwindow->signal_averaging_active = 0; mainwindow->setup_viewbuf(); return; } samples_on_screen = mainwindow->signalcomp[signal_nr]->samples_on_screen; avgbuf = (double *)calloc(1, sizeof(double) * samples_on_screen); if(avgbuf == NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "The system was not able to provide enough resources (memory) to perform the requested action."); messagewindow.exec(); mainwindow->edfheaderlist[0]->viewtime = backup_viewtime; mainwindow->pagetime = backup_timescale; mainwindow->signal_averaging_active = 0; mainwindow->setup_viewbuf(); return; } n = edfplus_annotation_count(&mainwindow->annotationlist[0]); avg_cnt = 0; for(i=0; iannotationlist[0], i); if(((annot->onset - mainwindow->edfheaderlist[0]->starttime_offset) >= l_time1) && ((annot->onset - mainwindow->edfheaderlist[0]->starttime_offset) <= l_time2)) { strcpy(str, annot->annotation); remove_trailing_spaces(str); if(!strcmp(str, annot_str)) { if(!(avg_cnt % progress_steps)) { progress.setValue(avg_cnt); qApp->processEvents(); if(progress.wasCanceled() == TRUE) { free(avgbuf); mainwindow->edfheaderlist[0]->viewtime = backup_viewtime; mainwindow->pagetime = backup_timescale; mainwindow->signal_averaging_active = 0; mainwindow->setup_viewbuf(); return; } } mainwindow->edfheaderlist[0]->viewtime = annot->onset; mainwindow->edfheaderlist[0]->viewtime -= mainwindow->edfheaderlist[0]->starttime_offset; mainwindow->edfheaderlist[0]->viewtime -= (mainwindow->pagetime / trigger_position_ratio); mainwindow->setup_viewbuf(); process_avg(mainwindow->signalcomp[signal_nr]); avg_cnt++; } } } progress.reset(); if(!avg_cnt) { sprintf(scratchpad, "The selected annotation/trigger \"%s\" is not in the selected timewindow\n" "%i:%02i:%02i - %i:%02i:%02i", annot_str, timeEdit1->time().hour(), timeEdit1->time().minute(), timeEdit1->time().second(), timeEdit2->time().hour(), timeEdit2->time().minute(), timeEdit2->time().second()); QMessageBox messagewindow(QMessageBox::Critical, "Error", scratchpad); messagewindow.exec(); free(avgbuf); mainwindow->edfheaderlist[0]->viewtime = backup_viewtime; mainwindow->pagetime = backup_timescale; mainwindow->signal_averaging_active = 0; mainwindow->setup_viewbuf(); return; } avg_max_value = -100000000.0; avg_min_value = 100000000.0; for(i=0; i avg_max_value) { avg_max_value = avgbuf[i]; } if(avgbuf[i] < avg_min_value) { avg_min_value = avgbuf[i]; } } mainwindow->averagecurvedialog[dialoglistnumber] = new UI_AverageCurveWindow(mainwindow->signalcomp[signal_nr], mainwindow, dialoglistnumber, avgbuf, avg_max_value, avg_min_value, mainwindow->pagetime, mainwindow->signalcomp[signal_nr]->samples_on_screen, avg_cnt, trigger_position_ratio, annot_str, avg_periodspinbox->value()); for(i=0; isignalcomp[signal_nr]->avg_dialog[i] == 0) { mainwindow->signalcomp[signal_nr]->avg_dialog[i] = dialoglistnumber + 1; break; } } } mainwindow->edfheaderlist[0]->viewtime = backup_viewtime; mainwindow->pagetime = backup_timescale; mainwindow->signal_averaging_active = 0; mainwindow->setup_viewbuf(); averager_dialog->close(); } UI_AveragerWindow::~UI_AveragerWindow() { int i; for(i=0; iaveragecurvedialog[i] != NULL) { mainwindow->averagecurvedialog[i]->averager_curve_dialog->move(((i % 15) * 30) + 200, ((i % 15) * 30) + 200); mainwindow->averagecurvedialog[i]->averager_curve_dialog->raise(); mainwindow->averagecurvedialog[i]->averager_curve_dialog->activateWindow(); } } } void UI_AveragerWindow::process_avg(struct signalcompblock *signalcomp) { int j, k; char *viewbuf; long long s, s2; double dig_value=0.0, f_tmp=0.0; union { unsigned int one; signed int one_signed; unsigned short two[2]; signed short two_signed[2]; unsigned char four[4]; } var; viewbuf = mainwindow->viewbuf; if(viewbuf == NULL) { return; } if(avgbuf == NULL) { return; } for(s=signalcomp->sample_start; ssamples_on_screen; s++) { if(s>signalcomp->sample_stop) break; dig_value = 0.0; s2 = s + signalcomp->sample_timeoffset - signalcomp->sample_start; for(j=0; jnum_of_signals; j++) { if(signalcomp->edfhdr->bdf) { var.two[0] = *((unsigned short *)( viewbuf + signalcomp->viewbufoffset + (signalcomp->edfhdr->recordsize * (s2 / signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].smp_per_record)) + signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].buf_offset + ((s2 % signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].smp_per_record) * 3))); var.four[2] = *((unsigned char *)( viewbuf + signalcomp->viewbufoffset + (signalcomp->edfhdr->recordsize * (s2 / signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].smp_per_record)) + signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].buf_offset + ((s2 % signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].smp_per_record) * 3) + 2)); if(var.four[2]&0x80) { var.four[3] = 0xff; } else { var.four[3] = 0x00; } f_tmp = var.one_signed; } if(signalcomp->edfhdr->edf) { f_tmp = *(((short *)( viewbuf + signalcomp->viewbufoffset + (signalcomp->edfhdr->recordsize * (s2 / signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].smp_per_record)) + signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].buf_offset)) + (s2 % signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].smp_per_record)); } f_tmp += signalcomp->edfhdr->edfparam[signalcomp->edfsignal[j]].offset; f_tmp *= signalcomp->factor[j]; dig_value += f_tmp; } for(k=0; kfilter_cnt; k++) { dig_value = first_order_filter(dig_value, signalcomp->filter[k]); } for(k=0; kravg_filter_cnt; k++) { if(s==signalcomp->sample_start) { ravg_filter_restore_buf(signalcomp->ravg_filter[k]); } dig_value = run_ravg_filter(dig_value, signalcomp->ravg_filter[k]); } for(k=0; kfidfilter_cnt; k++) { if(s==signalcomp->sample_start) { memcpy(signalcomp->fidbuf[k], signalcomp->fidbuf2[k], fid_run_bufsize(signalcomp->fid_run[k])); } dig_value = signalcomp->fidfuncp[k](signalcomp->fidbuf[k], dig_value); } if(signalcomp->ecg_filter != NULL) { if(s==signalcomp->sample_start) { ecg_filter_restore_buf(signalcomp->ecg_filter); } dig_value = run_ecg_filter(dig_value, signalcomp->ecg_filter); } avgbuf[s] += (dig_value * signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].bitvalue); } } edfbrowser_153_source/PaxHeaders.2978/z_ratio_filter.h0000644000175000001440000000013212251654530021334 xustar000000000000000030 mtime=1386699096.468032569 30 atime=1386699096.468032569 30 ctime=1386699096.468032569 edfbrowser_153_source/z_ratio_filter.h0000644000175000001440000000424212251654530021067 0ustar00novarausers00000000000000/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2012, 2013 Teunis van Beelen * * teuniz@gmail.com * *************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * *************************************************************************** * * This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt * *************************************************************************** */ #ifndef zratio_filter_INCLUDED #define zratio_filter_INCLUDED #include #include #include #include "global.h" #include "third_party/kiss_fft/kiss_fftr.h" struct zratio_filter_settings{ double crossoverfreq; int dftblocksize; double samplefreq; int fft_outputbufsize; double freqstep; double f1; double f2; double f3; double f4; double *fft_inputbuf; double *fft_outputbuf; kiss_fftr_cfg cfg; kiss_fft_cpx *kiss_fftbuf; int smpls_in_inputbuf; double zratio_value; double *fft_inputbuf_bu; int smpls_in_inputbuf_bu; double zratio_value_bu; double bitvalue; }; struct zratio_filter_settings * create_zratio_filter(int, long long, double, double); double run_zratio_filter(double, struct zratio_filter_settings *); void free_zratio_filter(struct zratio_filter_settings *); void reset_zratio_filter(struct zratio_filter_settings *); void zratio_filter_save_buf(struct zratio_filter_settings *); void zratio_filter_restore_buf(struct zratio_filter_settings *); #endif