diff -Naur --exclude Makefile --exclude info wfdb-10.5.18/app/gqrs.c wfdb-10.5.19/app/gqrs.c --- wfdb-10.5.18/app/gqrs.c 2012-05-06 13:56:09.000000000 -0400 +++ wfdb-10.5.19/app/gqrs.c 2013-07-21 13:02:54.000000000 -0400 @@ -1,8 +1,8 @@ /* file: gqrs.c G. Moody 16 November 2006 - Last revised: 23 April 2012 + Last revised: 21 July 2013 ------------------------------------------------------------------------------- gqrs: A QRS detector -Copyright (C) 2006-2012 George B. Moody +Copyright (C) 2006-2013 George B. Moody 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 @@ -701,7 +701,7 @@ " -h print this usage summary", " -H read multifrequency signals in high resolution mode", " -m THRESH set detector threshold to THRESH (default: 1.00)", - " -o RECORD save filtered signals in a new RECORD", + " -o ANN save annotations as annotator ANN (default: qrs)", " -s SIGNAL analyze specified SIGNAL (default: 0)", " (Note: SIGNAL may be specified by number or name.)", " -t TIME stop at specified time", diff -Naur --exclude Makefile --exclude info wfdb-10.5.18/doc/wag-src/gqrs.1 wfdb-10.5.19/doc/wag-src/gqrs.1 --- wfdb-10.5.18/doc/wag-src/gqrs.1 2012-05-05 19:35:56.000000000 -0400 +++ wfdb-10.5.19/doc/wag-src/gqrs.1 2013-07-21 09:22:26.000000000 -0400 @@ -1,4 +1,4 @@ -.TH GQRS 1 "5 May 2012" "WFDB 10.5.13" "WFDB Applications Guide" +.TH GQRS 1 "21 July 2013" "WFDB 10.5.19" "WFDB Applications Guide" .SH NAME gqrs, gqpost \- QRS detector and post-processor .SH SYNOPSIS @@ -7,22 +7,26 @@ \fBgqpost -r\fR \fIrecord\fR [ \fIoptions\fR ... ] .SH DESCRIPTION .PP -\fBgqrs\fR attempts to locate QRS complexes in an ECG signal in the -specified \fIrecord\fR. The detector algorithm is new and as yet -unpublished. The output of \fBgqrs\fR is an annotation file (with -annotator name \fBqrs\fR) in which all detected beats are labelled -normal ("N"). +\fBgqrs\fR attempts to locate QRS complexes in an ECG signal in the specified +\fIrecord\fR. The detector algorithm is new and as yet unpublished. The +output of \fBgqrs\fR is an annotation file (with annotator name \fBqrs\fR) in +which all detected beats are labelled normal ("N"). The \fIsubtyp\fR, +\fIchan\fR, and \fInum\fR fields of each annotation respectively indicate the +detection pass (0 or 1) during which the QRS complex was detected, the signal +number on which it was detected, and the peak amplitude of the detector's +matched filter during the QRS complex. .PP As a QRS detector for research, \fBgqrs\fR has been optimized for sensitivity. \fBgqpost\fR can post-process \fBgqrs\fR's output annotation file to improve -positive predictivity, at a cost of reduced sensitivity. It does this by -copying its input annotation file, changing N annotations into artifact -("!") annotations if they are likely to be erroneous. -.PP -A shared configuration file can be used to describe some of the expected -characteristics of the ECG signal. This is unnecessary when processing -adult human ECGs, but an appropriately constructed configuration file allows -\fBgqrs\fR to analyze fetal, pediatric, and animal ECGs. +positive predictivity, generally at a cost of reduced sensitivity. It does +this by copying its input annotation file, changing N annotations into artifact +("|") annotations if they are likely to be erroneous. +.PP +A configuration file shared by \fBgqrs\fR and \fBgqpost\fR can be used to +describe some of the expected characteristics of the ECG signal. This is +unnecessary when processing adult human ECGs, but an appropriately constructed +configuration file allows \fBgqrs\fR to analyze fetal, pediatric, and animal ECGs. A sample configuration file is available (see SOURCES, below); it contains +details about all configurable parameters. .PP \fIOptions\fR include: .TP @@ -101,4 +105,5 @@ .br http://www.physionet.org/physiotools/wfdb/app/gqpost.c .br -http://www.physionet.org/physiotools/wfdb/app/gqrs.conf +http://www.physionet.org/physiotools/wfdb/app/gqrs.conf (sample configuration +file) diff -Naur --exclude Makefile --exclude info wfdb-10.5.18/doc/wpg-src/wpg0.tex wfdb-10.5.19/doc/wpg-src/wpg0.tex --- wfdb-10.5.18/doc/wpg-src/wpg0.tex 2013-02-22 13:01:40.000000000 -0500 +++ wfdb-10.5.19/doc/wpg-src/wpg0.tex 2013-07-21 11:36:56.000000000 -0400 @@ -9051,7 +9051,14 @@ @unnumberedsec WFDB 10.5 -@unnumberedsubsec Changes in version 10.5.18 (22 February 2013) +@unnumberedsubsec Changes in version 10.5.19 (21 July 2013) + +This release includes fixes in lib/signal.c for several bugs that sometimes +caused @code{findsig()}, @code{getvec()}, and @code{sample()} to return +incorrect values when reading variable-layout multi-segment records with +missing signals. + +@unnumberedsubsec Changes in version 10.5.18 (16 February 2013) Function @code{wfdb_addtopath} now works properly if the path contained only one component on entry. diff -Naur --exclude Makefile --exclude info wfdb-10.5.18/fortran/wfdbf.c wfdb-10.5.19/fortran/wfdbf.c --- wfdb-10.5.18/fortran/wfdbf.c 2008-07-14 12:28:36.000000000 -0400 +++ wfdb-10.5.19/fortran/wfdbf.c 2013-07-21 17:21:03.000000000 -0400 @@ -1,9 +1,9 @@ /* file: wfdbf.c G. Moody 23 August 1995 - Last revised: 14 July 2008 wfdblib 10.4.7 + Last revised: 21 July 2013 wfdblib 10.5.19 _______________________________________________________________________________ wfdbf: Fortran wrappers for the WFDB library functions -Copyright (C) 1995-2008 George B. Moody +Copyright (C) 1995-2013 George B. Moody This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free @@ -212,10 +212,9 @@ sinfo, (unsigned int)(*nsig))); } -long setgvmode_(long int *mode) +long findsig_(char *signame) { - setgvmode((int)(*mode)); - return (0L); + return (findsig(fcstring(signame))); } long getspf_(long int *dummy) @@ -223,25 +222,25 @@ return (getspf()); } -long setifreq_(double *freq) +long setgvmode_(long int *mode) { - return (setifreq(*freq)); + setgvmode((int)(*mode)); + return (0L); } -double getifreq_(long int *dummy) +long getgvmode_(long int *dummy) { - return (getifreq()); + return (getgvmode()); } -long setafreq_(double *freq) +long setifreq_(double *freq) { - setafreq(*freq); - return (0L); + return (setifreq((WFDB_Frequency)*freq)); } -double getafreq_(long int *dummy) +double getifreq_(long int *dummy) { - return (getafreq()); + return (getifreq()); } long getvec_(long int *long_vector) @@ -353,6 +352,11 @@ return (isgsettime((WFDB_Group)(*group), (WFDB_Time)(*time))); } +long tnextvec_(long int *signal, long int *time) +{ + return (tnextvec((WFDB_Signal)(*signal), (WFDB_Time)(*time))); +} + long iannsettime_(long int *time) { return (iannsettime((WFDB_Time)(*time))); @@ -404,6 +408,17 @@ return (setanndesc((int)(*code), fcstring(string))); } +long setafreq_(double *freq) +{ + setafreq(*freq); + return (0L); +} + +double getafreq_(long int *dummy) +{ + return (getafreq()); +} + long iannclose_(long int *annotator) { iannclose((WFDB_Annotator)(*annotator)); @@ -416,6 +431,68 @@ return (0L); } +/* The functions below can be used in place of the macros defined in + . */ + +long isann_(long int *anntyp) +{ + return (wfdb_isann((int)*anntyp)); +} + +long isqrs_(long int *anntyp) +{ + return (wfdb_isqrs((int)*anntyp)); +} + +long setisqrs_(long int *anntyp, long int *value) +{ + wfdb_setisqrs((int)*anntyp, (int)*value); + return (0L); +} + +long map1_(long int *anntyp) +{ + return (wfdb_map1((int)*anntyp)); +} + +long setmap1_(long int *anntyp, long int *value) +{ + wfdb_setmap1((int)*anntyp, (int)*value); + return (0L); +} + +long map2_(long int *anntyp) +{ + return (wfdb_map2((int)*anntyp)); +} + +long setmap2_(long int *anntyp, long int *value) +{ + wfdb_setmap2((int)*anntyp, (int)*value); + return (0L); +} + +long ammap_(long int *anntyp) +{ + return (wfdb_ammap((int)*anntyp)); +} + +long mamap_(long int *anntyp, long int *subtyp) +{ + return (wfdb_mamap((int)*anntyp, (int)*subtyp)); +} + +long annpos_(long int *anntyp) +{ + return (wfdb_annpos((int)*anntyp)); +} + +long setannpos_(long int *anntyp, long int *value) +{ + wfdb_setannpos((int)*anntyp, (int)*value); + return (0L); +} + long timstr_(long int *time, char *string) { strcpy(string, timstr((WFDB_Time)(*time))); @@ -529,6 +606,17 @@ return (putinfo(fcstring(string))); } +long setinfo_(char *record) +{ + return (setinfo(fcstring(record))); +} + +long wfdb_freeinfo_(long int *dummy) +{ + wfdb_freeinfo(); + return (0L); +} + long newheader_(char *record) { return (newheader(fcstring(record))); @@ -541,7 +629,7 @@ return (setheader(fcstring(record), sinfo, (unsigned int)(*nsig))); } -/* No wrapper is provided for setmsheader. */ +/* No wrappers are provided for setmsheader or getseginfo. */ long wfdbgetskew_(long int *s) { @@ -571,6 +659,11 @@ return (0L); } +long wfdbputprolog_(char *prolog, long int *bytes, long int *signal) +{ + return (wfdbputprolog(fcstring(prolog), (long)*bytes,(WFDB_Signal)*signal)); +} + long wfdbquit_(long int *dummy) { wfdbquit(); @@ -646,6 +739,12 @@ return (0L); } +long resetwfdb_(long int *dummy) +{ + resetwfdb(); + return (0L); +} + long setibsize_(long int *input_buffer_size) { return (setibsize((int)(*input_buffer_size))); @@ -663,76 +762,49 @@ return (0L); } -long wfdbmemerr_(long int *exit_if_error) -{ - wfdbmemerr((int)(*exit_if_error)); - return (0L); -} - long wfdbflush_(long int *dummy) { wfdbflush(); return (0L); } -/* The functions below can be used in place of the macros defined in - . */ - -long isann_(long int *anntyp) -{ - return ((long)(isann(*anntyp))); -} - -long isqrs_(long int *anntyp) -{ - return ((long)(isqrs(*anntyp))); -} - -long setisqrs_(long int *anntyp, long int *value) -{ - setisqrs(*anntyp, *value); +long wfdbmemerr_(long int *exit_if_error) +{ + wfdbmemerr((int)(*exit_if_error)); return (0L); } -long map1_(long int *anntyp) -{ - return ((long)(map1(*anntyp))); -} - -long setmap1_(long int *anntyp, long int *value) -{ - setmap1(*anntyp, *value); +long wfdbversion_(char *version) +{ + strcpy(version, wfdbversion()); + cfstring(version); return (0L); } -long map2_(long int *anntyp) -{ - return ((long)(map1(*anntyp))); -} - -long setmap2_(long int *anntyp, long int *value) -{ - setmap1(*anntyp, *value); +long wfdbldflags_(char *ldflags) +{ + strcpy(ldflags, wfdbldflags()); + cfstring(ldflags); return (0L); } -long ammap_(long int *anntyp) -{ - return ((long)(ammap(*anntyp))); -} - -long mamap_(long int *anntyp, long int *subtyp) -{ - return ((long)(mamap(*anntyp, *subtyp))); +long wfdbcflags_(char *cflags) +{ + strcpy(cflags, wfdbcflags()); + cfstring(cflags); + return (0L); } -long annpos_(long int *anntyp) -{ - return ((long)(annpos(*anntyp))); +long wfdbdefwfdb_(char *defwfdb) +{ + strcpy(defwfdb, wfdbdefwfdb()); + cfstring(defwfdb); + return (0L); } -long setannpos_(long int *anntyp, long int *value) -{ - setannpos(*anntyp, *value); +long wfdbdefwfdbcal_(char *defwfdbcal) +{ + strcpy(defwfdbcal, wfdbdefwfdbcal()); + cfstring(defwfdbcal); return (0L); } diff -Naur --exclude Makefile --exclude info wfdb-10.5.18/INSTALL wfdb-10.5.19/INSTALL --- wfdb-10.5.18/INSTALL 2006-03-02 18:23:26.000000000 -0500 +++ wfdb-10.5.19/INSTALL 2013-07-21 13:03:18.000000000 -0400 @@ -1,5 +1,5 @@ file: INSTALL G. Moody 30 January 2000 - Last revised: 2 March 2006 + Last revised: 21 July 2013 WFDB Software Package installation notes These notes are infrequently updated, but are included here for those who may @@ -38,10 +38,11 @@ (all included in current Mac OS X CD sets) + MS-Windows: Install Cygwin, including (at least) the following optional - packages: bc, curl-devel, gcc, gcc-mingw, gv, ImageMagick, make, - sunrpc, and xorg-x11-devel. (Other required packages will be installed - automatically if those listed are selected.) Detailed instructions - are available at + packages: ImageMagick, X-start-menu-icons, bc, curl, cygutils-extra, + diffutils, gcc, gcc-fortran, gv, libX11-devel, libcurl-devel, + libexpat1-devel, make, sunrpc, twm, and xview-devel. (Other required + packages will be installed automatically if those listed are selected.) + Detailed instructions are available at http://physionet.org/physiotools/cygwin/ * An HTTP client library, either libcurl (preferred) or libwww @@ -61,7 +62,9 @@ * The XView libraries and *.h files - All platforms: free from http://physionet.org/physiotools/xview/ + + MS-Windows: install xview-devel from Cygwin (see above) + + + Other platforms: free from http://physionet.org/physiotools/xview/ Detailed instructions for obtaining and installing these prerequisites are included in the WFDB quick-start guides for the popular platforms (see above). @@ -76,15 +79,18 @@ 1. Open a terminal emulator window and navigate to the top-level directory of the WFDB sources (the directory that contains this file). -2. In this directory, build and install the WFDB Software Package by typing: +2. Configure the package by typing: ./configure + You will normally need root permissions (on MS-Windows, administrator + permissions) to run 'make install'. If you don't have root/administrator + permissions, use configure's --prefix option to specify a directory + in which you have permission to write, like this: + ./configure --prefix=/some/writable/directory + +3. Build and install the WFDB library and applications by typing: make install - Except under MS-Windows, you will normally need root permissions to run - 'make install'. If you don't have root permissions, set WFDBROOT to the - name of a directory in which you have permission to write (you will be - given a chance to do this when running 'configure'). -3. In this directory, test the installation by typing: +4. Test the installation by typing: make check If there are any errors, look in the checkpkg directory for details. diff -Naur --exclude Makefile --exclude info wfdb-10.5.18/lib/annot.c wfdb-10.5.19/lib/annot.c --- wfdb-10.5.18/lib/annot.c 2012-04-06 15:33:44.000000000 -0400 +++ wfdb-10.5.19/lib/annot.c 2013-03-25 17:42:04.000000000 -0400 @@ -960,7 +960,7 @@ (void)sprintf(cmdbuf, "sortann -r %s -a %s", oa->rname, oa->info.name); if (system(cmdbuf) == 0) { - wfdb_error("done!"); + wfdb_error("done!\n"); oa->out_of_order = 0; } else diff -Naur --exclude Makefile --exclude info wfdb-10.5.18/lib/signal.c wfdb-10.5.19/lib/signal.c --- wfdb-10.5.18/lib/signal.c 2012-09-27 08:50:21.000000000 -0400 +++ wfdb-10.5.19/lib/signal.c 2013-07-21 08:46:27.000000000 -0400 @@ -1,10 +1,10 @@ /* file: signal.c G. Moody 13 April 1989 - Last revised: 27 September 2012 wfdblib 10.5.1 + Last revised: 21 July 2013 wfdblib 10.5.19 WFDB library functions for signals _______________________________________________________________________________ wfdb: a library for reading and writing annotated waveforms (time series data) -Copyright (C) 1989-2012 George B. Moody +Copyright (C) 1989-2013 George B. Moody This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free @@ -253,7 +253,7 @@ static unsigned maxisig; /* max number of input signals */ static unsigned maxigroup; /* max number of input signal groups */ static unsigned nisig; /* number of open input signals */ -static unsigned nigroups; /* number of open input signal groups */ +static unsigned nigroup; /* number of open input signal groups */ static unsigned maxspf; /* max allowed value for ispfmax */ static unsigned ispfmax; /* max number of samples of any open signal per input frame */ @@ -299,7 +299,7 @@ static unsigned maxosig; /* max number of output signals */ static unsigned maxogroup; /* max number of output signal groups */ static unsigned nosig; /* number of open output signals */ -static unsigned nogroups; /* number of open output signal groups */ +static unsigned nogroup; /* number of open output signal groups */ static WFDB_FILE *oheader; /* file pointer for output header file */ static WFDB_FILE *outinfo; /* file pointer for output info file */ static struct osdata { /* unique for each output signal */ @@ -1207,14 +1207,13 @@ struct isdata *is; struct igdata *ig; - /* if (nisig == 0) return; */ if (sbuf && !in_msrec) { SFREE(sbuf); sample_vflag = 0; } if (isd) { - while (nisig) - if (is = isd[--nisig]) { + while (maxisig) + if (is = isd[--maxisig]) { SFREE(is->info.fname); SFREE(is->info.units); SFREE(is->info.desc); @@ -1222,22 +1221,18 @@ } SFREE(isd); } - else - nisig = 0; - maxisig = 0; + maxisig = nisig = 0; if (igd) { - while (nigroups) - if (ig = igd[--nigroups]) { + while (maxigroup) + if (ig = igd[--maxigroup]) { if (ig->fp) (void)wfdb_fclose(ig->fp); SFREE(ig->buf); SFREE(ig); } SFREE(igd); } - else - nigroups = 0; - maxigroup = 0; + maxigroup = nigroup = 0; istime = 0L; gvc = ispfmax = 1; @@ -1255,8 +1250,8 @@ struct ogdata *og; if (osd) { - while (nosig) - if (os = osd[--nosig]) { + while (maxosig) + if (os = osd[--maxosig]) { SFREE(os->info.fname); SFREE(os->info.units); SFREE(os->info.desc); @@ -1264,13 +1259,11 @@ } SFREE(osd); } - else - nosig = 0; - maxosig = 0; + nosig = 0; if (ogd) { - while (nogroups) - if (og = ogd[--nogroups]) { + while (maxogroup) + if (og = ogd[--maxogroup]) { if (og->fp) { /* If a block size has been defined, null-pad the buffer */ if (og->bsize) @@ -1290,9 +1283,7 @@ } SFREE(ogd); } - else - nogroups = 0; - maxogroup = 0; + maxogroup = nogroup = 0; ostime = 0L; if (oheader) { @@ -1527,7 +1518,7 @@ /* Do nothing if there is no more than one input signal group and the input pointer is correct already. */ - if (nigroups < 2 && istime == (in_msrec ? t + segp->samp0 : t) && + if (nigroup < 2 && istime == (in_msrec ? t + segp->samp0 : t) && igd[g]->start == 0) return (0); @@ -1727,7 +1718,7 @@ if (istime == 0L) { for (s = 0; s < nisig; s++) isd[s]->samp = isd[s]->info.initval; - for (g = nigroups; g; ) { + for (g = nigroup; g; ) { /* Go through groups in reverse order since seeking on group 0 should always be done last. */ if (--g == 0 || igd[g]->start > 0L) @@ -1959,7 +1950,7 @@ return (-1); /* failed, nisig is unchanged, allocisig emits error */ else nsig = nn; - nn = nigroups + hsd[nsig-nisig-1]->info.group + 1; + nn = nigroup + hsd[nsig-nisig-1]->info.group + 1; if (allocigroup(nn) != nn) return (-1); /* failed, allocigroup emits error */ else @@ -1974,7 +1965,7 @@ for (g = si = s = 0; si < navail && s < nsig; si = sj) { hs = hsd[si]; is = isd[nisig+s]; - ig = igd[nigroups+g]; + ig = igd[nigroup+g]; /* Find out how many signals are in this group. */ for (sj = si + 1; sj < navail; sj++) @@ -2012,7 +2003,7 @@ ig->stat = 1; while (si < sj && s < nsig) { copysi(&is->info, &hs->info); - is->info.group = nigroups + g; + is->info.group = nigroup + g; is->skew = hs->skew; ++s; if (++si < sj) { @@ -2043,7 +2034,7 @@ setgvmode(gvmode); /* Reset sfreq if appropriate. */ gvc = ispfmax; /* Initialize getvec's sample-within-frame counter. */ nisig += s; /* Update the count of open input signals. */ - nigroups += g; /* Update the count of open input signal groups. */ + nigroup += g; /* Update the count of open input signal groups. */ if (sigmap_init() < 0) return (-1); @@ -2102,7 +2093,7 @@ /* Allocate workspace for output signals. */ if (allocosig(nosig + nsig) < 0) return (-3); /* Allocate workspace for output signal groups. */ - if (allocogroup(nogroups + hsd[nsig-1]->info.group + 1) < 0) return (-3); + if (allocogroup(nogroup + hsd[nsig-1]->info.group + 1) < 0) return (-3); /* Initialize local variables. */ if (obsize <= 0) obsize = BUFSIZ; @@ -2110,7 +2101,7 @@ /* Set the group number adjustment. This quantity is added to the group numbers of signals which are opened below; it accounts for any output signals which were left open from previous calls. */ - ga = nogroups; + ga = nogroup; /* Open the signal files. One signal is handled per iteration. */ for (s = 0, os = osd[nosig]; s < nsig; s++, nosig++, siarray++) { @@ -2155,7 +2146,7 @@ return (-3); } } - nogroups++; + nogroup++; } else { /* This signal belongs to the same group as the previous signal. */ @@ -2281,7 +2272,7 @@ return (-3); } } - nogroups++; + nogroup++; } else { /* This signal belongs to the same group as the previous signal. */ @@ -2314,7 +2305,7 @@ q++; if (*q == 0) { /* all digits, probably a signal number */ s = atoi(p); - if (s < nisig) return (s); + if (s < nisig || s < nvsig) return (s); } /* Otherwise, p is either an integer too large to be a signal number or a string containing a non-digit character. Assume it's a signal name. */ @@ -2442,7 +2433,7 @@ FINT getvec(WFDB_Sample *vector) { - int i; + int i, nsig; if (ifreq == 0.0 || ifreq == sfreq) /* no resampling necessary */ return (rgetvec(vector)); @@ -2452,13 +2443,14 @@ rgvtime -= mnticks; gvtime -= mnticks; } + nsig = (nvsig > nisig) ? nvsig : nisig; while (gvtime > rgvtime) { - for (i = 0; i < nisig; i++) + for (i = 0; i < nsig; i++) gv0[i] = gv1[i]; rgvstat = rgetvec(gv1); rgvtime += nticks; } - for (i = 0; i < nisig; i++) { + for (i = 0; i < nsig; i++) { vector[i] = gv0[i] + (gvtime%nticks)*(gv1[i]-gv0[i])/nticks; gv0[i] = gv1[i]; } @@ -2471,7 +2463,7 @@ int stat; if (dsbuf) { /* signals must be deskewed */ - int c, i, j, s; + int c, i, j, nsig, s; /* First, obtain the samples needed. */ if (dsbi < 0) { /* dsbuf contents are invalid -- refill dsbuf */ @@ -2484,7 +2476,8 @@ if ((dsbi += framelen) >= dsblen) dsbi = 0; } /* Assemble the deskewed frame from the data in dsbuf. */ - for (j = s = 0; s < nisig; s++) { + nsig = (nvsig > nisig) ? nvsig : nisig; + for (j = s = 0; s < nsig; s++) { if ((i = j + dsbi + isd[s]->skew*framelen) >= dsblen) i -= dsblen; for (c = 0; c < isd[s]->info.spf; c++) vector[j++] = dsbuf[i++]; @@ -2585,7 +2578,7 @@ /* Return immediately if no seek is needed. */ if (t == istime || nisig == 0) return (0); - for (g = 1; g < nigroups; g++) + for (g = 1; g < nigroup; g++) if ((stat = isgsettime(g, t)) < 0) break; /* Seek on signal group 0 last (since doing so updates istime and would confuse isgsettime if done first). */ @@ -3487,17 +3480,18 @@ { static WFDB_Sample v; static WFDB_Time tt; + int nsig = (nvsig > nisig) ? nvsig : nisig; /* Allocate the sample buffer on the first call. */ if (sbuf == NULL) { - SALLOC(sbuf, nisig, BUFLN*sizeof(WFDB_Sample)); + SALLOC(sbuf, nsig, BUFLN*sizeof(WFDB_Sample)); tt = (WFDB_Time)-1L; } /* If the caller requested a sample from an unavailable signal, return an invalid value. Note that sample_vflag is not cleared in this case. */ - if (s < 0 || s >= nisig) { + if (s < 0 || s >= nsig) { sample_vflag = -1; return (WFDB_INVALID_SAMPLE); } @@ -3522,15 +3516,15 @@ more samples. If we reach the end of the record, clear sample_vflag and return the last valid value. */ while (t > tt) - if (getvec(sbuf + nisig * ((++tt)&(BUFLN-1))) < 0) { + if (getvec(sbuf + nsig * ((++tt)&(BUFLN-1))) < 0) { --tt; sample_vflag = 0; - return (*(sbuf + nisig * (tt&(BUFLN-1)) + s)); + return (*(sbuf + nsig * (tt&(BUFLN-1)) + s)); } /* The requested sample is in the buffer. Set sample_vflag and return the requested sample. */ - if ((v = *(sbuf + nisig * (t&(BUFLN-1)) + s)) == WFDB_INVALID_SAMPLE) + if ((v = *(sbuf + nsig * (t&(BUFLN-1)) + s)) == WFDB_INVALID_SAMPLE) sample_vflag = -1; else sample_vflag = 1; @@ -3589,7 +3583,7 @@ WFDB_Group g; struct ogdata *og; - for (g = 0; g < nogroups; g++) { + for (g = 0; g < nogroup; g++) { og = ogd[g]; if (og->bsize == 0 && og->bp != og->buf) { (void)wfdb_fwrite(og->buf, 1, og->bp - og->buf, og->fp); diff -Naur --exclude Makefile --exclude info wfdb-10.5.18/lib/wfdb.h wfdb-10.5.19/lib/wfdb.h --- wfdb-10.5.18/lib/wfdb.h 2013-02-22 13:04:41.000000000 -0500 +++ wfdb-10.5.19/lib/wfdb.h 2013-07-21 19:08:36.000000000 -0400 @@ -32,7 +32,7 @@ /* WFDB library version. */ #define WFDB_MAJOR 10 #define WFDB_MINOR 5 -#define WFDB_RELEASE 18 +#define WFDB_RELEASE 19 #define WFDB_NETFILES 1 /* if 1, library includes code for HTTP, FTP clients */ #define WFDB_NETFILES_LIBCURL 1 diff -Naur --exclude Makefile --exclude info wfdb-10.5.18/NEWS wfdb-10.5.19/NEWS --- wfdb-10.5.18/NEWS 2013-02-22 13:17:43.000000000 -0500 +++ wfdb-10.5.19/NEWS 2013-07-21 23:13:22.999232280 -0400 @@ -1,5 +1,11 @@ +10.5.19 (21 July 2013): + This release includes fixes in lib/signal.c for several bugs that + sometimes caused findsig(), getvec(), and sample() to return incorrect + values when reading variable-layout multi-segment records with missing + signals. + 10.5.18 (16 February 2013): - wfdb_addtopath now works properly if the path contained only one + wfdb_addtopath() now works properly if the path contained only one component on entry. 10.5.17 (2 January 2013): diff -Naur --exclude Makefile --exclude info wfdb-10.5.18/README.WINDOWS wfdb-10.5.19/README.WINDOWS --- wfdb-10.5.18/README.WINDOWS 2006-04-29 20:33:21.000000000 -0400 +++ wfdb-10.5.19/README.WINDOWS 2013-07-21 14:31:17.000000000 -0400 @@ -1,132 +1,134 @@ -file: README.WINDOWS G. Moody 8 June 2005 - Last revised: 29 April 2006 +file: README.WINDOWS G. Moody 8 June 2005 + Last revised: 21 July 2013 -This file contains additional notes about how to build the WFDB Software -Package under MS-Windows in various non-standard and unsupported ways. -We strongly recommend that all users follow the procedure described in -'INSTALL' in order to build a complete and compatible set of WFDB Software, -including WAVE, which is possible to build under MS-Windows only in this -way. - -There are two specific cases in which you might need another version of the -WFDB library binary under MS-Windows: - - * if you need to use the WFDB_tools wrappers with Matlab R14 (but not R13) - - * if you wish to link the WFDB library to other code that must also be linked - with Windows native libraries. - -In these cases, either of the two methods outlined below will allow you to -create a Windows native version of the WFDB library that does not depend on -Cygwin's POSIX emulation library. These methods also create a mostly complete -set of WFDB applications (except for WAVE) that are used to test the WFDB -library; use them at your own risk, since they may not behave in exactly the -same way as the standard versions of the same applications. - -Please note that these methods, and any others that do not use an ANSI/ISO -C compiler such as gcc, are UNSUPPORTED. Your feedback is welcome, but we -do not use any commercial compilers and cannot help you learn how to use them. - -............................................................................... - -Creating MinGW (Windows native) binaries - -The "Minimalist GNU for Windows" project (MinGW, http://www.mingw.org/) is "a -collection of freely available and freely distributable Windows specific header -files and import libraries combined with GNU toolsets that allow one to produce -native Windows programs that do not rely on any 3rd-party C runtime DLLs." You -can build the WFDB software with the MinGW gcc provided by Cygwin, or with the -minimal MSYS environment. - -Method A: (easy) - - Use a Cygwin (terminal emulator) window throughout the installation - below. We do not recommend attempting to build and install native - Windows binaries of the WFDB Software Package using a DOS window - (Windows Command Prompt). - - 1. First perform a standard WFDB installation from sources using Cygwin, - following the instructions in 'INSTALL'. - - 2. Select a location to install the MingGW WFDB binaries. We recommend - keeping them separate from the standard Cygwin paths to avoid confusion. - A good choice is '/opt/wfdb'. - - 3. Install a native Windows version of libcurl: - - a. Download the no-SSL libcurl binary package for Win32 from - http://curl.haxx.se/download/ - and move the zip file into your (Cygwin) home directory. - As of 29 April 2006, the most recent version of this file was: - libcurl-7.15.3-win32-nossl.zip - (The SSL and SSL+SSPI enabled versions of libcurl should also work if - the additional libraries they need are installed, but this has not been - tested. The WFDB library does not require SSL or SSPI support.) - - b. Create a directory for the native Windows binaries: - mkdir -p /opt/wfdb/bin - This command also creates /opt and /opt/wfdb if necessary. - - c. Unpack libcurl into /opt: - cd /opt - unzip ~/libcurl-*nossl.zip - The libcurl files will unpack into a version-numbered directory under - /opt, such as /opt/libcurl-7.15.3. Copy the needed files into /opt/wfdb: - cd /opt/libcurl-7.15.3 - cp -p bin/curl-config /opt/wfdb/bin - cp -p lib/* /opt/wfdb/bin - cp -pr include /opt/wfdb - - d. Edit /opt/wfdb/bin/curl-config, replacing - prefix=/usr/local - with - prefix=/opt/wfdb - and changing - echo -L$(exec_prefix)/lib -lcurl -L/home/dast/src/win32 ... - to - echo -L$(exec_prefix)/bin -lcurl - (deleting the remainder of the line following '-lcurl'). - - 4. Add /opt/wfdb/bin to the beginning of your PATH: - export PATH="/opt/wfdb/bin:$PATH" - replacing '/opt/wfdb' with your install path, if different. See - README.NETFILES for further information. - - Repeat this step whenever you start a new Cygwin window and wish to - use the native Windows WFDB binaries. - - 5. Use 'cd' to return to this directory (the top-level directory of the - WFDB Software Package, containing the file you are now reading), and type: - ./configure --no-cygwin --prefix=/opt/wfdb - make install - replacing '/opt/wfdb' with your install path, if different. - - Note: If you run - make check - many of the checks will fail because text files written by the WFDB - applications will be in DOS format (with CR+LF line terminators). This - is normal and is not an indication of problems. - - -Method B: (experts only) - - 1. If you have not already done so, install the MinGW compiler and the MSYS - shell environment (freely available from http://www.mingw.org/). These - include MinGW/gcc and an assortment of other GNU utilities ported - to MS-Windows. Accept the defaults suggested by the installer. - - 2. Open a MSYS terminal window (the MSYS installer will have added this to - your MS-Windows start menu). Check that 'which' and 'gcc' are accessible - by typing the command: - which gcc - The output of this command should be: - /mingw/bin/gcc - If you don't see this output, rerun the MinGW and MSYS installers. - - 3. Install libcurl (see steps 2-4 above). - - 4. In this directory (the top-level directory of the WFDB software package, - containing the file you are now reading), type: - ./configure - make install +Making a native Windows version of the WFDB library + +On MS-Windows, the procedure described in 'INSTALL' generates a WFDB library +that depends upon Cygwin's POSIX emulation library (cygwin1.dll) to provide a +Unix-like operating environment, thus assuring that WFDB applications will +behave on MS-Windows as much as possible like they do on other platforms. It is +also possible, though not generally recommended, to make a WFDB library that +depends only on the native libraries provided with MS-Windows. You might need a +native Windows version of the WFDB library if you wish to link it to other code +that must also be linked with Windows native libraries. + +The method outlined below will allow you to create a Windows native version of +the WFDB library that does not depend on Cygwin's POSIX emulation library or any +third party libraries other than those provided with MS-Windows, and +(optionally) curl, which the WFDB library uses for reading data directly from +web servers. It uses MinGW, a minimalist development environment for native +MS-Windows libraries and applications. + +1. Install MinGW and MSYS using the automated installer tool (mingw-get-inst, + also called the "Graphical User Interface Installer" or the "GUI first time + installer tool") following the instructions at + http://mingw.org/wiki/Getting_Started + Be sure to select the option to use the latest available packages. Use the + default installation directory (c:\mingw), and choose all of the optional + components. + +2. Download the most recent curl source tarball from + http://curl.haxx.se/download.html + As of June 2013, the most recent version was curl-7.31.0.tar.gz. Save it in + your MinGW home directory (by default, c:\MinGW\msys\1.0\home\User). + +3. Download the most recent WFDB source tarball from + http://physionet.org/physiotools/wfdb.tar.gz + and save it in your MinGW home directory. + +4. Open a MinGW terminal window by clicking on Start -> Programs -> MinGW -> + MinGW Shell. Perform the remaining steps of the installation by typing into + this window. + +5. Unpack the tarballs using these commands: + tar xfvz curl*.tar.gz + tar xfvz wfdb.tar.gz + These commands will create two directories, named curl-7.x.y and wfdb-10.m.n, + where x, y, m and n will depend on the version numbers of the packages you + have downloaded. + +6. Compile and install the curl package first: + cd curl-7.y.z + ./configure --prefix=/usr + make + make install + The ./configure and make commands may require several minutes each. + +7. Compile and install the WFDB Software Package after installing curl: + cd ../wfdb-10.m.n + ./configure --prefix=/usr + make + make install + +Notes: + +1. The native Windows libraries created by this procedure are installed in + c:\MinGW\msys\1.0\usr\bin; their names are libcurl-4.dll and wfdb-10.5.dll. + +2. A mostly complete set of WFDB applications (except for WAVE) is also + installed in the same directory. Use them at your own risk, since they may + not behave in exactly the same way as the standard versions of the same + applications. You can test the compiled WFDB library and applications using + make check + (either before or after 'make install'). A handful of the tests performed by + 'make check' will fail because they generate text files with MSDOS-style line + terminators that don't match the POSIX-style line terminators that + 'make check' expects; this is normal and is not an indication of problems. + +3. Copy the libraries and applications to a directory in your Windows PATH if + you want to run them using cmd.exe (as, for example, in a DOS box). Avoid + installing them in any location that has a space in its pathname. + +4. If you don't want your compiled WFDB library to be able to read data via + HTTP, you can skip steps 2 and 6 above, and add --without-netfiles to the + configure command in step 7. + +5. You may optionally install OpenSSL (http://openssl.org/) before configuring + and compiling curl (step 6) if you wish to use the compiled library or + applications to read data via HTTPS (for example, directly from your + PhysioNetWorks projects). OpenSSL is not required by WFDB applications for + reading data from local files or from web servers via HTTP. See + http://curl.haxx.se/docs/libs.html + for details on OpenSSL and other optional libraries. + + +Using a compiler other than gcc + +The procedure in the previous section uses MinGW's gcc to produce WFDB and curl +DLLs in Windows native format. You can use any other compiler that is compatible +with Windows DLLs to compile application code and link it to these WFDB and curl +DLLs, and to other third-party DLLs if you wish. + +It is not possible to compile or use WAVE under MS-Windows except by using +Cygwin gcc and the Cygwin X11 and XView libraries. + +Compiling the WFDB library with a compiler other than gcc is unsupported. gcc is +free, is of very high quality, and is supported; if you use another compiler, +you are on your own. Your feedback is welcome, but we do not use any commercial +compilers and cannot help you learn how to use them. + +If you do not use gcc, you must do one of the following: + + * Use your compiler in ANSI/ISO C mode if this is supported (see your compiler + documentation), or + + * Define the symbol MSDOS (to any value) when compiling the WFDB Software + Package. + +If you do neither of these steps, your compiler will generate a defective WFDB +DLL that assumes that files are always opened in so-called text mode, resulting +in errors when reading and writing signal and annotation files (which are binary +files). You can check to see if this has happened by running the command + + rdsamp -r 100s + +which should yield 21600 numbered lines of output, ending with + + 21596 982 995 + 21597 978 989 + 21598 975 988 + 21599 975 989 + +If the output ends after 940 lines, you have a defective WFDB DLL and you will +need to follow the instructions above to correct the problem.