diff -Naur --exclude Makefile --exclude info wfdb-10.4.11/app/calsig.c wfdb-10.4.12/app/calsig.c --- wfdb-10.4.11/app/calsig.c 2002-11-14 17:14:50.000000000 -0500 +++ wfdb-10.4.12/app/calsig.c 2009-01-07 13:49:48.000000000 -0500 @@ -1,9 +1,9 @@ /* file: calsig.c G. Moody 4 March 1991 - Last revised: 14 November 2002 + Last revised: 7 January 2009 ------------------------------------------------------------------------------- calsig: measure gains and baselines in a WFDB record and rewrite header -Copyright (C) 2002 George B. Moody +Copyright (C) 1991-2009 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 @@ -198,7 +198,7 @@ for (i = 0; i < nsig; i++) do_cal[i] = 0; for (i = 0; i < ncsig; i++) { - n = atoi(argv[isiglist+i]); + n = findsig(argv[isiglist+i]); if (0 <= n && n < nsig) do_cal[i] = 1; } diff -Naur --exclude Makefile --exclude info wfdb-10.4.11/app/pschart.c wfdb-10.4.12/app/pschart.c --- wfdb-10.4.11/app/pschart.c 2006-06-02 12:30:49.000000000 -0400 +++ wfdb-10.4.12/app/pschart.c 2009-01-16 15:21:19.000000000 -0500 @@ -1,9 +1,9 @@ /* file: pschart.c G. Moody 15 March 1988 - Last revised: 2 June 2006 + Last revised: 15 January 2009 ------------------------------------------------------------------------------- pschart: Produce annotated `chart recordings' on a PostScript device -Copyright (C) 1988-2006 George B. Moody +Copyright (C) 1988-2009 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 @@ -163,6 +163,7 @@ mm/unit above strips; 4: units/tick above strips; 5: mm/unit within strips; 6: units/ tick within strips) */ +char **snstr; /* signal names (if provided on command line) */ char *sqstr; /* signal quality string (1 char/signal) */ double tpmv = TPMV; /* grid ticks per millivolt */ double tps = TPS; /* grid ticks per second */ @@ -175,6 +176,9 @@ bug in the Adobe TranScript package */ int vflag = 0; /* if non-zero, echo commands */ double vscale = VSCALE; /* voltage scale (mm/millivolt) */ +int xflag = 0; /* if non-zero, plot only in (xvmin, xvmax) */ +int xvmax; /* high end of range if xflag set */ +int xvmin; /* low end of range if xflag set */ double h_sep = H_SEP; /* horizontal space between strips (mm) */ double l_sep = L_SEP; /* distance from labels to sides of grid */ @@ -448,9 +452,10 @@ pname); exit(1); } - /* allocate storage for the signal list and for sqstr */ + /* allocate storage for the signal list, snstr, and sqstr */ if (j - i > nomax) { if ((siglist = realloc(siglist, (j-i)*sizeof(int))) == NULL || + (snstr = realloc(sqstr, (j-i+1)*sizeof(char *))) == NULL || (sqstr = realloc(sqstr, (j-i+1)*sizeof(char))) == NULL) { (void)fprintf(stderr, "%s: insufficient memory\n", pname); exit(2); @@ -459,7 +464,7 @@ /* fill the signal list */ nosig = 0; while (++i < j) - siglist[nosig++] = atoi(argv[i]); + snstr[nosig++] = argv[i]; i--; break; case 'S': /* set modes for scale and time stamp printing */ @@ -515,6 +520,17 @@ exit(1); } break; + case 'x': /* specify range of raw sample values to be plotted */ + if (++i >= argc-1) { + (void)fprintf(stderr, + "%s: sample range must follow -x\n", + pname); + exit(1); + } + xflag = 1; + xvmin = atoi(argv[i++]); + xvmax = atoi(argv[i]); + break; case '1': /* abbreviate aux strings to one character on output */ aux_shorten = 1; break; @@ -643,14 +659,15 @@ nosig = nisig; } else { - for (i = 0; i < nosig; i++) - if (siglist[i] < 0 || siglist[i] >= nisig) { + for (i = 0; i < nosig; i++) { + if ((siglist[i] = findsig(snstr[i])) < 0) { (void)fprintf(stderr, - "record %s doesn't have a signal %d\n", - record, siglist[i]); + "record %s doesn't have a signal '%s'\n", + record, snstr[i]); wfdbquit(); return; } + } } if (nisig > nimax) { if ((uncal = realloc(uncal, nisig * sizeof(int))) == NULL || @@ -763,7 +780,9 @@ for (i = 0; i < nosig; i++) { int vtmp = v[siglist[i]]; - vbuf[i][j] = vmax[i] = vmin[i] = vtmp; + if (xflag && (vtmp > xvmax || vtmp < xvmin)) + vtmp = WFDB_INVALID_SAMPLE; + vbuf[i][j] = vtmp; if (vtmp != WFDB_INVALID_SAMPLE) { if (vtmp > vmax[i] || vmax[i] == WFDB_INVALID_SAMPLE) vmax[i] = vtmp; @@ -1104,6 +1123,7 @@ int x, y, c; unsigned int ia; + if (iannsettime(t0) < 0 && nann == 1) return (1); setrgbcolor(&ac); setroman(fs_ann); @@ -1113,6 +1133,7 @@ else c = -1; while (getann(ia, &annot) >= 0 && annot.time < t1) { + if (annot.time == 0) continue; if (Mflag >= 2 && annot.chan != c) { int i, j; i = c = annot.chan; @@ -1834,6 +1855,7 @@ " -v N set voltage scale to N mm/mV (default: 5)", /* ** VSCALE ** */ " -V verbose mode", " -w N set line width to N mm (default: 0.2; 0 is narrowest possible)", + " -x MIN MAX plot samples only if raw values are between MIN and MAX", " -1 print only first character of comment annotation strings", " - read script from standard input", "Script line format:", diff -Naur --exclude Makefile --exclude info wfdb-10.4.11/app/psfd.c wfdb-10.4.12/app/psfd.c --- wfdb-10.4.11/app/psfd.c 2006-06-02 12:33:32.000000000 -0400 +++ wfdb-10.4.12/app/psfd.c 2009-01-07 15:01:48.000000000 -0500 @@ -1,9 +1,9 @@ /* file: psfd.c G. Moody 9 August 1988 - Last revised: 2 June 2006 + Last revised: 7 January 2009 ------------------------------------------------------------------------------- psfd: Produces annotated full-disclosure ECG plots on a PostScript device -Copyright (C) 1988-2006 George B. Moody +Copyright (C) 1988-2009 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 @@ -157,6 +157,7 @@ int *siglist; /* list of signals to be printed */ int smode = 1; /* scale mode (0: no scales; 1: mm/unit in footers; 2: units/tick in footers) */ +char **snstr; /* signal names (if provided on command line) */ char *sqstr; /* signal quality string (1 char/signal) */ double t_hideal = 7.5; /* ideal value for t_height (see below) */ double tps = TPS; /* grid ticks per second */ @@ -422,9 +423,10 @@ pname); exit(1); } - /* allocate storage for the signal list and for sqstr */ + /* allocate storage for the signal list, snstr, and sqstr */ if (j - i > nomax) { if ((siglist = realloc(siglist, (j-i)*sizeof(int))) == NULL || + (snstr = realloc(sqstr, (j-i+1)*sizeof(char *))) == NULL || (sqstr = realloc(sqstr, (j-i+1)*sizeof(char))) == NULL) { (void)fprintf(stderr, "%s: insufficient memory\n", pname); exit(2); @@ -433,7 +435,7 @@ /* fill the signal list */ nosig = 0; while (++i < j) - siglist[nosig++] = atoi(argv[i]); + snstr[nosig++] = argv[i]; i--; break; case 'S': /* set modes for scale and time stamp printing */ @@ -636,14 +638,15 @@ nosig = nisig; } else { - for (i = 0; i < nosig; i++) - if (siglist[i] < 0 || siglist[i] >= nisig) { + for (i = 0; i < nosig; i++) { + if ((siglist[i] = findsig(snstr[i])) < 0) { (void)fprintf(stderr, - "record %s doesn't have a signal %d\n", - record, siglist[i]); + "record %s doesn't have a signal '%s'\n", + record, snstr[i]); wfdbquit(); return; } + } } if (nisig > nimax) { if ((uncal = realloc(uncal, nisig * sizeof(int))) == NULL || diff -Naur --exclude Makefile --exclude info wfdb-10.4.11/app/rdsamp.c wfdb-10.4.12/app/rdsamp.c --- wfdb-10.4.11/app/rdsamp.c 2005-09-09 16:17:12.000000000 -0400 +++ wfdb-10.4.12/app/rdsamp.c 2009-01-07 13:36:00.000000000 -0500 @@ -1,9 +1,9 @@ /* file: rdsamp.c G. Moody 23 June 1983 - Last revised: 29 June 2005 + Last revised: 7 January 2009 ------------------------------------------------------------------------------- rdsamp: Print an arbitrary number of samples from each signal -Copyright (C) 1983-2004 George B. Moody +Copyright (C) 1983-2009 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 @@ -48,6 +48,11 @@ #define WFDBP ";\\mghdb" #endif +/* values for timeunits */ +#define SECONDS 1 +#define MINUTES 2 +#define HOURS 3 + char *pname; main(argc, argv) @@ -56,7 +61,7 @@ { char *record = NULL, *prog_name(); int highres = 0, i, isiglist, nsig, nosig = 0, pflag = 0, s, *sig = NULL, - vflag = 0; + timeunits = SECONDS, vflag = 0; long from = 0L, maxl = 0L, to = 0L; WFDB_Sample *v; WFDB_Siginfo *si; @@ -127,6 +132,9 @@ break; case 'p': /* output in physical units specified */ ++pflag; + if (*(argv[i]+2) == 'h') timeunits = HOURS; + else if (*(argv[i]+2) == 'm') timeunits = MINUTES; + else timeunits = SECONDS; break; case 's': /* signal list follows */ isiglist = i+1; /* index of first argument containing a signal # */ @@ -195,8 +203,9 @@ } #endif for (i = 0; i < nosig; i++) { - if ((s = atoi(argv[isiglist+i])) < 0 || s >= nsig) { - (void)fprintf(stderr, "%s: can't read signal %d\n", pname, s); + if ((s = findsig(argv[isiglist+i])) < 0) { + (void)fprintf(stderr, "%s: can't read signal '%s'\n", pname, + argv[isiglist+i]); exit(2); } sig[i] = s; @@ -256,9 +265,15 @@ char *p, *fmt = pflag > 1 ? "\t%15.8lf" : "\t%7.3f"; double freq = sampfreq(NULL); + if (timeunits == HOURS) freq *= 3600.; + else if (timeunits == MINUTES) freq *= 60.; + /* Print units as a second line of column headers if '-v' selected. */ if (vflag) { - (void)printf("(sec)"); + if (timeunits == HOURS) (void)printf("(hrs)"); + else if (timeunits == MINUTES) (void)printf("(min)"); + else if (timeunits == SECONDS) (void)printf("(sec)"); + for (i = 0; i < nsig; i++) { p = si[sig[i]].units; if (p == NULL) p = "mV"; @@ -270,7 +285,7 @@ } while ((to == 0L || from < to) && getvec(v) >= 0) { - (void)printf("%7.3lf", (double)(from++)/freq); + (void)printf("%7.3lf", (double)(from++)/freq); for (i = 0; i < nsig; i++) { if (v[sig[i]] != WFDB_INVALID_SAMPLE) (void)printf(fmt, @@ -322,7 +337,8 @@ " -H read multifrequency signals in high resolution mode", " -l INTERVAL truncate output after the specified time interval (hh:mm:ss)", " -p print times and samples in physical units (default: raw units)", - " (use -p -p for greater precision)", + " (use -p -p for greater precision; use -ph, -pm, or -ps to", + " print times in hours, minutes, or seconds respectively", " -s SIGNAL [SIGNAL ...] print only the specified signal(s)", " -t TIME stop at specified time", " -v print column headings", diff -Naur --exclude Makefile --exclude info wfdb-10.4.11/app/sortann.c wfdb-10.4.12/app/sortann.c --- wfdb-10.4.11/app/sortann.c 2000-01-30 04:13:17.000000000 -0500 +++ wfdb-10.4.12/app/sortann.c 2009-01-20 14:29:48.000000000 -0500 @@ -1,8 +1,8 @@ /* file sortann.c G. Moody 7 April 1997 - Last revised: 4 May 1999 + Last revised: 20 January 2009 ------------------------------------------------------------------------------- sortann: Rearrange annotations in canonical order -Copyright (C) 1999 George B. Moody +Copyright (C) 1997-2009 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 @@ -24,9 +24,9 @@ It is possible to create an annotation file containing out-of-order annotations. This program rewrites such files with the annotations in time -order. Any simultaneous annotations are written in `chan' order. +order. Any simultaneous annotations are written in 'num' and 'chan' order. -If the input contains two or more annotations with the same time and chan +If the input contains two or more annotations with the same time, num, and chan fields, only the last one is copied. As a special case of this policy, if the last such annotation has anntyp = 0 (NOTQRS), no annotation is written at that location (thus a program that generates input for sortann can effectively @@ -50,12 +50,10 @@ when using the -f or -t options (to avoid replacing the entire input file with a sorted subset of its contents). -Running out of memory is unlikely unless: - 1. you have less than 2 Mb of memory and you are attempting to sort a 24-hour - or longer annotation file. - 2. you have compiled sortann using a 16-bit compiler and you are attempting - to sort more than about 4000 annotations (note that the precompiled - versions of sortann for MS-DOS and UNIX do not have this limitation). +The working memory required by sortann is approximately 10 times the size of +the annotation file. Since annotation files are rarely as large as 1 megabyte +and available memory is rarely less than 10 megabytes, it is unlikely that +sortann will exhaust available memory, however. */ #include @@ -246,9 +244,10 @@ copybytes(p, pa->aux, *(pa->aux)+2); (newp->annotation).aux = p; } - if (lastp == &annlist || pa->time > (lastp->annotation).time || - (pa->time == (lastp->annotation).time && - pa->chan > (lastp->annotation).chan)) { + if (lastp == &annlist || + pa->chan > (lastp->annotation).chan || + pa->num > (lastp->annotation).num || + pa->time > (lastp->annotation).time) { /* this annotation is in order -- add to end of list */ newp->prev = lastp; lastp->next = newp; @@ -264,6 +263,9 @@ while (ap) { if (pa->time > (ap->annotation).time || (pa->time == (ap->annotation).time && + pa->num > (ap->annotation).num) || + (pa->time == (ap->annotation).time && + pa->num == (ap->annotation).num && pa->chan >= (ap->annotation).chan)) { break; } @@ -276,7 +278,8 @@ (newp->next)->prev = annlist.next = newp; } else if (pa->time == (ap->annotation).time && - pa->chan == (ap->annotation).chan) { /* replace ap by newp */ + pa->num == (ap->annotation).num && + pa->chan == (ap->annotation).chan) { /* replace ap by newp */ if (newp->prev = ap->prev) (newp->prev)->next = newp; if (newp->next = ap->next) (newp->next)->prev = newp; else lastp = newp; diff -Naur --exclude Makefile --exclude info wfdb-10.4.11/app/sqrs125.c wfdb-10.4.12/app/sqrs125.c --- wfdb-10.4.11/app/sqrs125.c 2008-01-14 23:13:29.000000000 -0500 +++ wfdb-10.4.12/app/sqrs125.c 2009-01-07 14:14:00.000000000 -0500 @@ -1,9 +1,9 @@ /* file: sqrs125.c G. Moody 27 October 1990 - Last revised: 14 January 2008 + Last revised: 7 January 2009 ------------------------------------------------------------------------------- sqrs125: Single-channel QRS detector for data sampled at 100 - 150 Hz -Copyright (C) 1990-2008 George B. Moody +Copyright (C) 1990-2009 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 @@ -27,17 +27,17 @@ Guide, which in turn is based on a Pascal program written by W.A.H. Engelse and C. Zeelenberg, "A single scan algorithm for QRS-detection and feature extraction", Computers in Cardiology 6:37-42 (1979). `sqrs' does not include -the feature extraction capability of the Pascal program. The output of `sqrs' +the feature extraction capability of the Pascal program. The output of sqrs125 is an annotation file (with annotator name `qrs') in which all detected beats are labelled normal; the annotation file may also contain `artifact' -annotations at locations which `sqrs' believes are noise-corrupted. +annotations at locations which `sqrs125' believes are noise-corrupted. The filter calculations and default thresholds used by this version have been optimized for signals sampled at 125 Hz, and may be used for signals sampled at rates between 100 and 150 Hz. (The original program, sqrs.c, was intended for use with signals sampled at 250 Hz). -`sqrs' can process records containing any number of signals, but it uses only +sqrs125 can process records containing any number of signals, but it uses only one signal for QRS detection (signal 0 by default; this can be changed using the `-s' option, see below). For best results on adult human ECGs, use `xform' to resample the input signal at 125 Hz if a significantly different sampling @@ -53,7 +53,7 @@ significantly better performance. Usage: - sqrs -r RECORD [ OPTIONS ] + sqrs125 -r RECORD [ OPTIONS ] where RECORD is the record name, and OPTIONS may include: -f TIME to specify the starting TIME (default: the beginning of the record) @@ -68,11 +68,11 @@ For example, to mark QRS complexes in record 100 beginning 5 minutes from the start, ending 10 minutes and 35 seconds from the start, and using signal 1, use the command: - sqrs -r 100 -f 5:0 -t 10:35 -s 1 + sqrs125 -r 100 -f 5:0 -t 10:35 -s 1 The output may be read using (for example): rdann -a qrs -r 100 To evaluate the performance of this program, run it on the entire record, by: - sqrs -r 100 + sqrs125 -r 100 and then compare its output with the reference annotations by: bxb -r 100 -a atr qrs */ @@ -136,11 +136,12 @@ break; case 's': /* signal */ if (++i >= argc) { - (void)fprintf(stderr, "%s: signal number must follow -s\n", + (void)fprintf(stderr, + "%s: signal number or name must follow -s\n", pname); exit(1); } - signal = atoi(argv[i]); + signal = findsig(argv[i]); break; case 't': /* end time */ if (++i >= argc) { diff -Naur --exclude Makefile --exclude info wfdb-10.4.11/app/sqrs.c wfdb-10.4.12/app/sqrs.c --- wfdb-10.4.11/app/sqrs.c 2008-05-15 17:51:47.000000000 -0400 +++ wfdb-10.4.12/app/sqrs.c 2009-01-07 14:11:23.000000000 -0500 @@ -1,9 +1,9 @@ /* file: sqrs.c G. Moody 27 October 1990 - Last revised: 15 May 2008 + Last revised: 7 January 2009 ------------------------------------------------------------------------------- sqrs: Single-channel QRS detector -Copyright (C) 1990-2008 George B. Moody +Copyright (C) 1990-2009 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 @@ -128,11 +128,12 @@ break; case 's': /* signal */ if (++i >= argc) { - (void)fprintf(stderr, "%s: signal number must follow -s\n", + (void)fprintf(stderr, + "%s: signal number or name must follow -s\n", pname); exit(1); } - signal = atoi(argv[i]); + signal = findsig(argv[i]); break; case 't': /* end time */ if (++i >= argc) { diff -Naur --exclude Makefile --exclude info wfdb-10.4.11/app/wabp.c wfdb-10.4.12/app/wabp.c --- wfdb-10.4.11/app/wabp.c 2007-09-07 10:57:42.000000000 -0400 +++ wfdb-10.4.12/app/wabp.c 2009-01-07 14:30:35.000000000 -0500 @@ -1,8 +1,8 @@ /* file wabp.c Wei Zong 23 October 1998 - Last revised: 25 February 2006 (by G. Moody) + Last revised: 7 January 2009 (by G. Moody) ----------------------------------------------------------------------------- wabp: beat detector for arterial blood presure (ABP) signal -Copyright (C) 1998-2006 Wei Zong +Copyright (C) 1998-2009 Wei Zong 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 @@ -171,11 +171,12 @@ break; case 's': /* signal */ if (++i >= argc) { - (void)fprintf(stderr, "%s: signal number must follow -s\n", + (void)fprintf(stderr, + "%s: signal number or name must follow -s\n", pname); exit(1); } - sig = atoi(argv[i]); + sig = findsig(argv[i]); break; case 't': /* end time */ if (++i >= argc) { @@ -403,7 +404,7 @@ " -h print this usage summary", " -H read multifrequency signals in high resolution mode", " -R resample input at 125 Hz (default: do not resample)", - " -s SIGNAL analyze specified signal (default: 0)", +" -s SIGNAL analyze specified signal (default: first ABP, ART, or BP signal)", " -t TIME stop at specified time (default: end of the record)", " -v verbose mode", " ", diff -Naur --exclude Makefile --exclude info wfdb-10.4.11/app/wfdbdesc.c wfdb-10.4.12/app/wfdbdesc.c --- wfdb-10.4.11/app/wfdbdesc.c 2008-01-09 00:14:21.000000000 -0500 +++ wfdb-10.4.12/app/wfdbdesc.c 2009-01-15 12:30:25.000000000 -0500 @@ -66,8 +66,8 @@ (void)printf("Record %s", argv[1]); setgvmode(WFDB_LOWRES); t = strtim("e"); - if (nsig > 0 && s[0].nsamp != t) { - msrec = 1; + if (nsig > 0 && (s[0].fmt == 0 || s[0].nsamp != 0) && s[0].nsamp != t) { + msrec = 1; (void)printf(" (a %s-layout multi-segment record)\n", s[0].nsamp == 0L ? "variable" : "fixed"); if (s[0].nsamp != 0L) { diff -Naur --exclude Makefile --exclude info wfdb-10.4.11/app/wqrs.c wfdb-10.4.12/app/wqrs.c --- wfdb-10.4.11/app/wqrs.c 2008-08-12 15:48:51.000000000 -0400 +++ wfdb-10.4.12/app/wqrs.c 2009-01-07 14:17:42.000000000 -0500 @@ -1,8 +1,8 @@ /* file: wqrs.c Wei Zong 23 October 1998 - Last revised: 12 August 2008 (by G. Moody) + Last revised: 7 January 2009 (by G. Moody) ----------------------------------------------------------------------------- wqrs: Single-lead QRS detector based on length transform -Copyright (C) 1998-2008 Wei Zong +Copyright (C) 1998-2009 Wei Zong 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 @@ -217,11 +217,12 @@ break; case 's': /* signal */ if (++i >= argc) { - (void)fprintf(stderr, "%s: signal number must follow -s\n", + (void)fprintf(stderr, + "%s: signal number or name must follow -s\n", pname); exit(1); } - sig = atoi(argv[i]); + sig = findsig(argv[i]); break; case 't': /* end time */ if (++i >= argc) { diff -Naur --exclude Makefile --exclude info wfdb-10.4.11/app/xform.c wfdb-10.4.12/app/xform.c --- wfdb-10.4.11/app/xform.c 2008-07-15 15:27:48.000000000 -0400 +++ wfdb-10.4.12/app/xform.c 2009-01-15 11:57:27.000000000 -0500 @@ -1,9 +1,9 @@ /* file: xform.c G. Moody 8 December 1983 - Last revised: 15 July 2008 + Last revised: 7 January 2009 ------------------------------------------------------------------------------- xform: Sampling frequency, amplitude, and format conversion for WFDB records -Copyright (C) 1983-2008 George B. Moody +Copyright (C) 1983-2009 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 @@ -158,7 +158,7 @@ } /* fill the signal list */ for (i -= j; i < argc && *argv[i] != '-'; ) - siglist[nosig++] = atoi(argv[i++]); + siglist[nosig++] = i++; i--; break; case 'S': /* script name follows */ @@ -209,6 +209,10 @@ value, quit (isigopen will have emitted an error message). */ if ((nisig = isigopen(irec, NULL, 0)) < 0) exit(2); + /* Determine the input sampling frequency. */ + ifreq = sampfreq(NULL); + (void)setsampfreq(0.); + /* If the input record contains no signals, we won't write any -- but we might still read and write annotations. */ if (nisig == 0) nosig = 0; @@ -221,20 +225,27 @@ exit(2); } + /* Open the input signals. */ + if (isigopen(irec, dfin, nisig) != nisig) exit(2); + /* If a signal list was specified using -s, check that the specified - signal numbers are legal. */ + signal numbers or names are legal. */ if (sflag) { - for (i = 0; i < nosig && nosig > 0; i++) - if (siglist[i] < 0 || siglist[i] >= nisig) { + for (i = 0; i < nosig && nosig > 0; i++) { + char *s; + + s = argv[siglist[i]]; + if ((siglist[i] = findsig(s)) < 0) { (void)fprintf(stderr, - "%s: warning: signal %d can't be read from record %s\n", - pname, siglist[i], irec); + "%s: warning: record %s doesn't have a signal '%s'\n", + pname, irec, s); /* Delete illegal signal numbers from the list. */ for (j = i; j+1 < nosig; j++) siglist[j] = siglist[j+1]; nosig--; i--; } + } /* If the signal list contained no valid signal numbers, treat this situation as if no signal list was specified. */ if (nosig == 0) @@ -267,12 +278,6 @@ } } - /* Determine the input sampling frequency. */ - ifreq = sampfreq(NULL); - (void)setsampfreq(0.); - - if (isigopen(irec, dfin, nisig) != nisig) exit(2); - if (Hflag) setgvmode(WFDB_HIGHRES); ifreq *= spf = getspf(); @@ -1108,7 +1113,7 @@ "desired signal files, you will be asked for output specifications. Use", "`-n' to name the record to be created. Use `-s' to select a subset of the", "input signals, or to re-order them in the output file; arguments that", - "follow `-s' are *input* signal numbers (0,1,2,...).", + "follow `-s' are *input* signal numbers (0,1,2,...) or names.", NULL }; diff -Naur --exclude Makefile --exclude info wfdb-10.4.11/checkpkg/expected/pschart.ps wfdb-10.4.12/checkpkg/expected/pschart.ps --- wfdb-10.4.11/checkpkg/expected/pschart.ps 2007-09-17 13:11:28.000000000 -0400 +++ wfdb-10.4.12/checkpkg/expected/pschart.ps 2009-01-16 13:11:01.000000000 -0500 @@ -92,7 +92,7 @@ (MLII)b 1612 2782 m (MLII)t -862 2793 m +862 2790 m (~O~O}N~O}O~Q~N}O~O}O~O~O}O~N}O~O~P}O~O}O~N}O~O~P}O~O}N~O~P}O~P}N~O~O}O~O}O~O~O}O~N}O~O}N~O~N}O~P}O~N~O}M~P}P~P~N}N~P}O~P}O~O~N}O~P}O~Q~P}N~P}P~O~P}O~P}O~O~P}O~O}P~N}P~O~O}O~O}O~O~O}P~O}N~O~O}P~O}O~N}N~O~O}P~O}N~N~P}O~P}N~O~O}O~O}O~O~O}N~P}O~O}O~O~O}O) z (~O}O~O~N}O~O}O~O~P}N~N}O~P}O~P~M}O~P}P~O~O}N~N}P~P~O}O~N}N~O~O}P~O}O~N}P~O~P}N~O}O~O~P}O~O}N~O~O}P~O}O~O~O}O~P}P~O}O~O~P}P~O}O~O~O}P~O}P~O~N}O~O}O~O}O~O~N}O~O}P~O~N}N~P}P~Q~N}N~M}N~N~O}N~N}O~N}P~N~P}O~O}O~O~P}O~N}O~N~P}O~N}O~N}O~P~P}O~N}N~P~N}O~M}M~M) z (~N}N~N}N~S~W}X~Y}^~^}]~W~R}I~=}7~:~D}M~Q}Q~Q~N}O~N}Q~O}N~O~N}O~P}O~O~O}N~P}O~O~O}N~P}O~P~O}O~O}N~O}P~O~O}O~O}O~O~O}O~N}O~P~O}O~O}O~N}O~P~O}O~O}N~O~P}O~O}O~N~O}P~O}O~N~O}O~O}P~O}O~O~O}O~O}O~O~N}O~P}O~N~O}N~O}P~O~O}N~O}P~N}O~P~N}O~O}P~P~O}P~O}P~P~P}O~O) z diff -Naur --exclude Makefile --exclude info wfdb-10.4.11/doc/wag-src/calsig.1 wfdb-10.4.12/doc/wag-src/calsig.1 --- wfdb-10.4.11/doc/wag-src/calsig.1 2002-07-28 10:45:53.000000000 -0400 +++ wfdb-10.4.12/doc/wag-src/calsig.1 2009-01-07 15:04:05.000000000 -0500 @@ -1,4 +1,4 @@ -.TH CALSIG 1 "28 July 2002" "WFDB 10.2.7" "WFDB Applications Guide" +.TH CALSIG 1 "7 January 2009" "WFDB 10.4.12" "WFDB Applications Guide" .SH NAME calsig \- calibrate signals of a WFDB record .SH SYNOPSIS @@ -64,7 +64,7 @@ .TP \fB-s\fR \fIsignal-list\fR Calibrate only the signals named in the \fIsignal-list\fR (one or more input -signal numbers, separated by spaces; default: calibrate all signals). +signal numbers or names, separated by spaces; default: calibrate all signals). .TP \fB-t\fI time\fR Process until the specified \fItime\fR in \fIrecord\fR (default: 1 second after diff -Naur --exclude Makefile --exclude info wfdb-10.4.11/doc/wag-src/pschart.1 wfdb-10.4.12/doc/wag-src/pschart.1 --- wfdb-10.4.11/doc/wag-src/pschart.1 2005-12-02 10:12:43.000000000 -0500 +++ wfdb-10.4.12/doc/wag-src/pschart.1 2009-01-07 15:08:07.000000000 -0500 @@ -1,4 +1,4 @@ -.TH PSCHART 1 "2 September 2005" "WFDB 10.3.18" "WFDB Applications Guide" +.TH PSCHART 1 "7 January 2009" "WFDB 10.3.12" "WFDB Applications Guide" .SH NAME pschart \- produce annotated `chart recordings' on a PostScript device .SH SYNOPSIS @@ -167,7 +167,7 @@ .TP \fB-s\fR \fIsignal-list\fR Print only the signals named in the \fIsignal-list\fR (one or more signal -numbers, separated by spaces; default: print all signals). +numbers or names, separated by spaces; default: print all signals). .TP \fB-S\fR \fIscale-mode timestamp-mode\fR Print scales and timestamps in the specified modes. Legal values for diff -Naur --exclude Makefile --exclude info wfdb-10.4.11/doc/wag-src/psfd.1 wfdb-10.4.12/doc/wag-src/psfd.1 --- wfdb-10.4.11/doc/wag-src/psfd.1 2005-09-02 22:07:53.000000000 -0400 +++ wfdb-10.4.12/doc/wag-src/psfd.1 2009-01-07 15:09:25.000000000 -0500 @@ -1,4 +1,4 @@ -.TH PSFD 1 "2 September 2005" "WFDB 10.3.18" "WFDB Applications Guide" +.TH PSFD 1 "7 January 2009" "WFDB 10.4.12" "WFDB Applications Guide" .SH NAME psfd \- produce annotated `full-disclosure' plots on a PostScript device .SH SYNOPSIS @@ -152,7 +152,7 @@ .TP \fB-s\fR\fR \fIsignal-list\fR Print only the signals named in the \fIsignal-list\fR (one or more signal -numbers, separated by spaces; default: print all signals). +numbers or names, separated by spaces; default: print all signals). .TP \fB-S\fR \fIscale-mode timestamp-mode\fR Print scales and timestamps in the specified modes. Legal values for diff -Naur --exclude Makefile --exclude info wfdb-10.4.11/doc/wag-src/rdsamp.1 wfdb-10.4.12/doc/wag-src/rdsamp.1 --- wfdb-10.4.11/doc/wag-src/rdsamp.1 2002-11-07 22:39:54.000000000 -0500 +++ wfdb-10.4.12/doc/wag-src/rdsamp.1 2009-01-07 15:06:49.000000000 -0500 @@ -1,4 +1,4 @@ -.TH RDSAMP 1 "7 November 2002" "WFDB 10.3.0" "WFDB Applications Guide" +.TH RDSAMP 1 "7 January 2009" "WFDB 10.4.12" "WFDB Applications Guide" .SH NAME rdsamp \- read WFDB signal files .SH SYNOPSIS @@ -35,12 +35,13 @@ Print times in seconds and milliseconds, and values in physical units. By default, \fBrdsamp\fR prints times in sample intervals and values in A/D units. Use \fB-p -p\fR to obtain higher precision in the sample values -(8 decimal places rather than 3). +(8 decimal places rather than 3). Use \fB-pm\fR or \fB-ph\fR to print times +in minutes or hours respectively. .TP \fB-s\fR \fIsignal-list\fR Print only the signals named in the \fIsignal-list\fR (one or more input signal -numbers, separated by spaces; default: print all signals). This option may be -used to re-order or duplicate signals. +numbers or names, separated by spaces; default: print all signals). This option +may be used to re-order or duplicate signals. .TP \fB-t\fR \fItime\fR Stop at the specified \fItime\fR. By default, \fBrdsamp\fR stops at the end diff -Naur --exclude Makefile --exclude info wfdb-10.4.11/doc/wag-src/sortann.1 wfdb-10.4.12/doc/wag-src/sortann.1 --- wfdb-10.4.11/doc/wag-src/sortann.1 2002-07-31 23:08:50.000000000 -0400 +++ wfdb-10.4.12/doc/wag-src/sortann.1 2009-01-20 19:37:06.000000000 -0500 @@ -1,4 +1,4 @@ -.TH SORTANN 1 "31 July 2002" "WFDB 10.2.7" "WFDB Applications Guide" +.TH SORTANN 1 "20 January 2009" "WFDB 10.4.12" "WFDB Applications Guide" .SH NAME sortann \- rearrange annotations in canonical order .SH SYNOPSIS @@ -7,10 +7,10 @@ Applications that use the WFDB library (version 9.7 and later versions) may write annotations in any order. Most applications that read annotations, however, expect to find them in \fItime\fR order (with simultaneous annotations -ordered by their \fIchan\fR attributes). +ordered by their \fInum\fR and \fIchan\fR attributes). .PP \fBsortann\fR rewrites the annotation file specified by \fIrecord\fR and -\fIannotator\fR, arranging its contents in canonical (\fItime\fR and +\fIannotator\fR, arranging its contents in canonical (\fItime\fR, \fInum\fR, and \fIchan\fR) order. By default, WFDB applications run \fBsortann\fR as needed (from within \fIwfdbquit\fR or \fIoannclose\fR). If the environment variable \fBWFDBNOSORT\fR has been set (to any value), \fBsortann\fR will not @@ -18,12 +18,12 @@ such cases, you should run \fBsortann\fR as instructed by the warning message before reading the annotation file with any other WFDB application. .PP -If the input contains two or more annotations with the same \fItime\fR and -\fIchan\fR fields, only the last one is copied. As a special case of this -policy, if the last such annotation has \fIanntyp\fR = 0 (\fBNOTQRS\fR), no -annotation is written at that location. Thus a program that generates input -for \fBsortann\fR can effectively delete a previously written annotation by -writing a \fBNOTQRS\fR annotation at the same location. +If the input contains two or more annotations with the same \fItime\fR, +\fInum\fR, and \fIchan\fR fields, only the last one is copied. As a special +case of this policy, if the last such annotation has \fIanntyp\fR = 0 +(\fBNOTQRS\fR), no annotation is written at that location. Thus a program that +generates input for \fBsortann\fR can effectively delete a previously written +annotation by writing a \fBNOTQRS\fR annotation at the same location. .PP The sorted (output) annotation file is always written to the current directory. If the input annotation file is in the current directory, \fBsortann\fR @@ -43,16 +43,10 @@ options (to avoid replacing the entire input file with a sorted subset of its contents). .PP -Running out of memory is unlikely unless: -.TP -1. -you have less than 2 Mb of memory and you are attempting to sort a 24-hour -or longer annotation file. -.TP -2. -you have compiled \fBsortann\fR using a 16-bit compiler and you are -attempting to sort more than about 4000 annotations (note that the precompiled -versions of \fBsortann\fR for MS-DOS and UNIX do not have this limitation). +The working memory required by \fBsortann\fR is approximately 10 times the size +of the annotation file. Since annotation files are rarely as large as 1 +megabyte and available memory is rarely less than 10 megabytes, it is unlikely +that \fBsortann\fR will exhaust available memory, however. .PP \fIOptions\fR include: .TP diff -Naur --exclude Makefile --exclude info wfdb-10.4.11/doc/wag-src/sqrs.1 wfdb-10.4.12/doc/wag-src/sqrs.1 --- wfdb-10.4.11/doc/wag-src/sqrs.1 2006-02-25 22:25:00.000000000 -0500 +++ wfdb-10.4.12/doc/wag-src/sqrs.1 2009-01-07 15:10:55.000000000 -0500 @@ -1,4 +1,4 @@ -.TH SQRS 1 "25 February 2006" "WFDB 10.4.0" "WFDB Applications Guide" +.TH SQRS 1 "7 January 2009" "WFDB 10.4.12" "WFDB Applications Guide" .SH NAME sqrs, sqrs125 \- single-channel QRS detector .SH SYNOPSIS @@ -65,7 +65,7 @@ beats. .TP \fB-s\fR \fIsignal\fR -Specify the \fIsignal\fR to be used for QRS detection (default: 0). +Specify the \fIsignal\fR (number or name) to be used for QRS detection (default: 0). .TP \fB-t\fR \fItime\fR Process until the specified \fItime\fR in \fIrecord\fR (default: the end of the diff -Naur --exclude Makefile --exclude info wfdb-10.4.11/doc/wag-src/wabp.1 wfdb-10.4.12/doc/wag-src/wabp.1 --- wfdb-10.4.11/doc/wag-src/wabp.1 2006-02-25 22:25:42.000000000 -0500 +++ wfdb-10.4.12/doc/wag-src/wabp.1 2009-01-07 15:11:52.000000000 -0500 @@ -1,4 +1,4 @@ -.TH WABP 1 "25 February 2006" "WFDB 10.4.0" "WFDB Applications Guide" +.TH WABP 1 "7 January 2009" "WFDB 10.4.12" "WFDB Applications Guide" .SH NAME wabp \- arterial blood pressure (ABP) pulse detector .SH SYNOPSIS @@ -48,8 +48,8 @@ Resample the input at 125 Hz (default: do not resample). .TP \fB-s\fR \fIsignal\fR -Specify the \fIsignal\fR to be used for ABP pulse detection (default: the -lowest-numbered ABP, ART, or BP signal). +Specify the \fIsignal\fR (number or name) to be used for ABP pulse detection +(default: the lowest-numbered ABP, ART, or BP signal). .TP \fB-t\fR \fItime\fR Process until the specified \fItime\fR in \fIrecord\fR (default: the end of the diff -Naur --exclude Makefile --exclude info wfdb-10.4.11/doc/wag-src/wqrs.1 wfdb-10.4.12/doc/wag-src/wqrs.1 --- wfdb-10.4.11/doc/wag-src/wqrs.1 2006-02-25 22:26:20.000000000 -0500 +++ wfdb-10.4.12/doc/wag-src/wqrs.1 2009-01-07 15:12:34.000000000 -0500 @@ -1,4 +1,4 @@ -.TH WQRS 1 "25 February 2006" "WFDB 10.4.0" "WFDB Applications Guide" +.TH WQRS 1 "7 January 2009" "WFDB 10.4.12" "WFDB Applications Guide" .SH NAME wqrs \- single-channel QRS detector based on length transform .SH SYNOPSIS @@ -66,7 +66,8 @@ 150 Hz otherwise (default: do not resample). .TP \fB-s\fR \fIsignal\fR -Specify the \fIsignal\fR to be used for QRS detection (default: 0). +Specify the \fIsignal\fR (number or name) to be used for QRS detection +(default: 0). .TP \fB-t\fR \fItime\fR Process until the specified \fItime\fR in \fIrecord\fR (default: the end of the diff -Naur --exclude Makefile --exclude info wfdb-10.4.11/doc/wag-src/xform.1 wfdb-10.4.12/doc/wag-src/xform.1 --- wfdb-10.4.11/doc/wag-src/xform.1 2008-04-18 12:43:32.000000000 -0400 +++ wfdb-10.4.12/doc/wag-src/xform.1 2009-01-07 15:13:27.000000000 -0500 @@ -1,4 +1,4 @@ -.TH XFORM 1 "18 April 2008" "WFDB 10.4.7" "WFDB Applications Guide" +.TH XFORM 1 "7 January 2009" "WFDB 10.4.12" "WFDB Applications Guide" .SH NAME xform \- sampling frequency, amplitude, and format conversion for WFDB records .SH SYNOPSIS @@ -77,8 +77,8 @@ .TP \fB-s\fR \fIsignal-list\fR Write only the signals named in the \fIsignal-list\fR (one or more input signal -numbers, separated by spaces; default: write all signals). This option may be -used to re-order or duplicate signals. +numbers or names, separated by spaces; default: write all signals). This option +may be used to re-order or duplicate signals. .TP \fB-S\fR \fIscript\fR Take answers to prompts from the specified \fIscript\fR (a text file). diff -Naur --exclude Makefile --exclude info wfdb-10.4.11/doc/wpg-src/wpg0.tex wfdb-10.4.12/doc/wpg-src/wpg0.tex --- wfdb-10.4.11/doc/wpg-src/wpg0.tex 2008-10-27 16:26:21.000000000 -0400 +++ wfdb-10.4.12/doc/wpg-src/wpg0.tex 2009-01-20 19:47:07.000000000 -0500 @@ -510,6 +510,41 @@ WFDB Software Package distribution, for information on any more recent changes that may not be described here. +@unnumberedsubsec Changes in version 10.4.12 + +The rule for sorting annotations within a file has been changed to allow a much +larger number of simultaneous annotations (i.e., annotations in a given +annotation file with identical @code{time} fields) than was previously +possible. Since version 6.1, the WFDB library sorts simultaneous annotations +according to the value of their @code{chan} fields, allowing for 256 +simultaneous annotations at any given time. Beginning in version 10.4.12, the +library sorts simultaneous annotations according to their @code{num} fields, +then sorts those with identical @code{num} fields according to their +@code{chan} fields, allowing up to 65,536 simultaneous annotations at any given +time. + +A new WFDB library function, @code{findsig}, returns the signal number of the +input signal matching its string argument, or -1 if no such input signal +exists. If the string argument could be interpreted as an input signal number, +it is taken as such; otherwise, the string argument must be an exact match to a +signal name (@code{desc} field in the @code{siginfo} structure). + +Previous versions of WFDB library function @code{setifreq} entered an infinite +loop if invoked (contrary to specifications) before opening an input record. +@code{setifreq} now detects the error, emits an appropriate warning, and +returns. + +If a WFDB application that uses WFDB library version 10.4.5 through 10.4.11 +attempted to read an annotation file before reading the sampling frequency of +the associated record (for example, by invoking @code{isigopen} or +@code{sampfreq}), the annotation times might all appear to be zero. This may +occur when reading annotations created using WFDB 10.4.5 or later. The times +supplied when creating the file are correctly written but may be incorrectly +read in these cases. This problem was corrected in this release; thanks to +Thomas Heldt for reporting it and providing a reproducible example of it. + +(WFDB library version 10.4.11 was identical to version 10.4.10.) + @unnumberedsubsec Changes in version 10.4.10 EDF digital maximum and minimum values are now read properly in 64-bit @@ -3870,6 +3905,7 @@ * sampfreq:: Reading the sampling frequency of a WFDB record. * setsampfreq:: Setting the sampling frequency. * setbasetime:: Setting the base time. +* findsig:: Finding a signal by name. * counter conversion:: Functions for reading and setting counter conversion parameters. * setwfdb:: Dynamically changing the database path. @@ -4322,7 +4358,7 @@ @xref{Example 8}, for an illustration of the use of @code{setsampfreq}. @c @group -@node setbasetime, counter conversion, setsampfreq, miscellaneous functions +@node setbasetime, findsig, setsampfreq, miscellaneous functions @unnumberedsubsec setbasetime @findex setbasetime @cindex current time @@ -4350,7 +4386,7 @@ the date should be separated from the time by a space or tab character. If @var{string} is empty or @code{NULL}, the current date and time are read from the system clock. Use @code{setbasetime} after defining the sampling -frequency and before creating a header file +frequency and before creating a header file. @ifnotinfo (@pxref{newheader, , @code{newheader}}). @end ifnotinfo @@ -4359,10 +4395,47 @@ @end ifinfo @xref{Example 8}, for an illustration of the use of @code{setbasetime}. +There is no @code{getbasetime} function; use @code{mstimstr(0)} at any +time after opening a record to convert the base date and time into a string. + +@sp 2 + +@c @group +@node findsig, counter conversion, setbasetime, miscellaneous functions +@findex findsig (10.4.12) +@cindex signal name +@cindex signal number +@cindex finding signal by name +@cindex signal lookup + +@example +int findsig(char *@var{string}) +@end example +@noindent +@strong{Return:} +@table @asis +@item @t{ WFDB_Signal} +Success +@item @t{-1} +Failure: signal not found +@end table +@c @end group + +@noindent +This function converts its argument to an input signal number. +If @var{string} is numeric and can be interpreted as a valid +input signal number, it is taken as such; otherwise, it is +assumed to be a signal name, and if it is an exact match to the +@code{desc} field of a currently open input signal's @code{siginfo} +structure, @code{findsig} returns the corresponding signal number. +If two or more signals have identical matching names, @code{findsig} +returns the lowest matching signal number. + + @sp 2 @c @group -@node counter conversion, setwfdb, setbasetime, miscellaneous functions +@node counter conversion, setwfdb, findsig, miscellaneous functions @cindex base counter value @cindex counter (base) @cindex counter frequency @@ -5337,7 +5410,7 @@ @code{ACMAX} is defined in @file{}. @item signed char subtyp -@itemx signed char chan +@itemx unsigned char chan @itemx signed char num @cindex annotation subtype @cindex subtype (annotation) @@ -5355,7 +5428,7 @@ indicate which signals are affected (@pxref{Annotation Codes}). The @code{chan} field is intended to indicate the signal to which the annotation is attached. More than one annotation may be written with -the same @code{time} if the @code{chan} fields are distinct and in +the same @code{time} if the @code{num} or @code{chan} fields are distinct and in ascending order. The semantics of the @code{chan} field are unspecified, however; users may assign any desired meaning, which need not have anything to do with signal numbers. In user-created annotation @@ -6167,22 +6240,23 @@ @cindex canonical order of annotations @cindex order of annotations -WFDB applications may generally assume (and most of them do assume) that -all annotations in any given annotation file are in @dfn{canonical -order}. Successful use of @code{iannsettime} requires that this assumption -be correct. Early versions of the WFDB library (before version 6.2) defined -canonical order as time order. More recent versions of the WFDB library define -canonical order as @code{time} and @code{chan} order (thus annotations -are arranged first in @code{time} order, and any simultaneous annotations are -arranged according to the value of their @code{chan} fields, from -smallest to largest). +WFDB applications may generally assume (and most of them do assume) that all +annotations in any given annotation file are in @dfn{canonical order}. +Successful use of @code{iannsettime} requires that this assumption be correct. +The earliest versions of the WFDB library (before version 6.1) defined +canonical order as time order. Versions 6.1 through 10.4.11 define canonical +order as @code{time} and @code{chan} order, and versions 10.4.12 and later also +use @code{num} for ordering (thus annotations are arranged first in @code{time} +order, and any simultaneous annotations are arranged according to the value of +their @code{num} fields, from smallest to largest, and those with identical +@code{num} fields are similarly arranged in @code{chan} order). @cindex location (of annotation) @cindex annotation location @cindex virtual array of annotations @cindex annotation (canonical order) @cindex canonical order of annotations -The combination of the @code{time} and @code{chan} fields of an +The combination of the @code{time}, @code{num}, and @code{chan} fields of an annotation defines a unique @dfn{location} in a virtual array of annotations which an annotation file represents. No two annotations may occupy the same location in this virtual array. This restriction was @@ -6210,15 +6284,15 @@ or more annotations to the same location, @emph{only the last annotation written to any given location is retained} in the canonically-ordered annotation file. Thus that an application that generates an annotation file -can change the @code{anntyp}, @code{subtyp}, @code{num}, or @code{aux} fields -of a previously-written annotation simply by writing another annotation to the -same location (i.e, with the same @code{time} and @code{chan} fields). As a -special case, an application may @emph{delete} a previously-written annotation -by writing a @code{NOTQRS} annotation to the same location. To move an -annotation to a different location (i.e., to change its @code{time} or -@code{chan} fields), it is necessary to delete it from the original location, -and then to insert it at the desired location, using two separate invocations -of @code{putann}. +can change the @code{anntyp}, @code{subtyp}, or @code{aux} fields of a +previously-written annotation simply by writing another annotation to the same +location (i.e, with the same @code{time}, @code{num}, and @code{chan} fields). +As a special case, an application may @emph{delete} a previously-written +annotation by writing a @code{NOTQRS} annotation to the same location. To move +an annotation to a different location (i.e., to change its @code{time}, +@code{num}, or @code{chan} fields), it is necessary to delete it from the +original location, and then to insert it at the desired location, using two +separate invocations of @code{putann}. @cindex unsorted annotation files @cindex @code{WFDBANNSORT} (environment variable) @@ -7874,7 +7948,7 @@ @item Location [of an annotation] @cindex location (of annotations) @cindex annotation location (defined) -Every annotation has both @code{time} and @code{chan} attributes that +Every annotation has @code{time}, @code{num}, and @code{chan} attributes that define its location within a virtual array of annotations. See @dfn{Canonical order of annotations}. @@ -7883,11 +7957,11 @@ @cindex canonical order of annotations Normally, annotations are arranged in time order within an annotation file. Annotations that have identical @code{time} attributes are arranged in -@code{chan} order. Annotations that have identical @dfn{locations} (i.e., -identical @code{time} and @code{chan} attributes) should not normally occur in -a single annotation file; if this does happen, the last annotation at any given -location is treated as a replacement of any previous annotations at that -location. +@code{num} and @code{chan} order. Annotations that have identical +@dfn{locations} (i.e., identical @code{time}, @code{num}, and @code{chan} +attributes) should not normally occur in a single annotation file; if this does +happen, the last annotation at any given location is treated as a replacement +of any previous annotations at that location. @item Low-resolution mode @cindex low-resolution mode (defined) diff -Naur --exclude Makefile --exclude info wfdb-10.4.11/doc/wug-src/wug0.tex wfdb-10.4.12/doc/wug-src/wug0.tex --- wfdb-10.4.11/doc/wug-src/wug0.tex 2008-07-14 11:50:16.000000000 -0400 +++ wfdb-10.4.12/doc/wug-src/wug0.tex 2009-01-13 17:14:51.000000000 -0500 @@ -64,10 +64,10 @@ For information on obtaining the most recent version of \WAVE{}, visit \begin{htmlonly} -\htmladdnormallink{PhysioNet}{http://www.physionet.org/}, or write to: +\htmladdnormallink{PhysioNet}{http://physionet.org/}, or write to: \end{htmlonly} \begin{latexonly} -PhysioNet ({\tt http://www.physionet.org/}), or write to: +PhysioNet ({\tt http://physionet.org/}), or write to: \end{latexonly} \begin{quote} @@ -83,12 +83,12 @@ \htmladdnormallink{PostScript}{wug.ps} and \htmladdnormallink{PDF}{wug.pdf} versions of this guide are available. The latest versions can be downloaded from -\htmladdnormallink{MIT}{http://www.physionet.org/}. +\htmladdnormallink{MIT}{http://physionet.org/}. \end{htmlonly} \begin{latexonly} \noindent An HTML version of this guide is available at -{\tt http://www.\-physio\-net.\-org/\-physio\-tools/\-wug/}. +{\tt http://physio\-net.\-org/\-physio\-tools/\-wug/}. \end{latexonly} \vspace{0.2 in} @@ -123,7 +123,7 @@ \begin{itemize} \item \htmladdnormallink{PhysioNet} -{http://www.physionet.org/} \\ +{http://physionet.org/} \\ Freely available databases of ECGs and other physiologic signals, and related software. The PhysioNet web site is a public service of the PhysioNet Resource funded by the National Institutes of Health's @@ -245,7 +245,7 @@ file:\-/usr\-/local\-/help\-/wave\-/wug.htm} if you have installed \WAVE{} on your system, or to\\ {\tt -http://www.physionet.org\-/physiotools\-/wug/}\\ +http://physionet.org\-/physiotools\-/wug/}\\ otherwise). \end{latexonly} \begin{htmlonly} @@ -257,7 +257,7 @@ \htmladdnormallink{here}{wug.ps}. The most recent \LaTeX{}, HTML, PDF, and PostScript versions can be obtained from \htmladdnormallink{PhysioNet} -{http://www.physionet.org/}. +{http://physionet.org/}. I would be grateful for reports of any typographic or other problems in the HTML version, since the translation to HTML is automated and may be less than perfect. Note that the distributed HTML version uses @@ -792,7 +792,7 @@ input files for wave. For more information, type `more /usr/help/wave/wave.hlp', -or open `http://www.physionet.org/physiotools/wug/' using +or open `http://physionet.org/physiotools/wug/' using your web browser. \end{verbatim} \noindent @@ -3395,10 +3395,10 @@ includes the current directory and the {\tt /usr/database} directory (on the \WAVE{} host), and PhysioBank's archives at \begin{htmlonly} -\htmladdnormallink{\tt http://www.\-physio\-net.\-org/\-physio\-bank/\-data\-base}{http://www.physionet.org/physiobank/database/} +\htmladdnormallink{\tt http://physio\-net.\-org/\-physio\-bank/\-data\-base}{http://physionet.org/physiobank/database/} \end{htmlonly} \begin{latexonly} -{\tt http://www.\-physio\-net.\-org/\-physio\-bank/\-data\-base} +{\tt http://physio\-net.\-org/\-physio\-bank/\-data\-base} \end{latexonly} (if the Internet is accessible from the \WAVE{} host). @@ -4831,7 +4831,7 @@ Database}\index{MIT-BIH Polysomnographic Database} \index{MGH/MF Waveform Database} You may find that an existing database of digitally recorded signals may be useful for your studies. PhysioNet, at -\htmladdnormallink{http://www.physionet.org/,}{http:/www.physionet.org/}, +\htmladdnormallink{http://physionet.org/,}{http:/physionet.org/}, offers free on-line access to over 40 such databases with thousands of recordings ranging in length from a few seconds to several days. These include all or most of the MIT-BIH Arrhythmia Database, the @@ -4879,8 +4879,8 @@ \WAVE{} makes extensive use of other components of the \emph{WFDB Software Package} of which it is a part. The most recent version of this package is always freely available from PhysioNet -(\htmladdnormallink{{\tt http://www.physionet.org/}} -{http://www.physionet.org/}). The WFDB Software Package includes +(\htmladdnormallink{{\tt http://physionet.org/}} +{http://physionet.org/}). The WFDB Software Package includes {\tt calsig}, {\tt mrgann}, {\tt plot2d}, {\tt pschart}, {\tt psfd}, {\tt rdann}, {\tt rdsamp}, {\tt sample}, {\tt snip}, {\tt sqrs}, {\tt tach}, {\tt wfdbcollate}, {\tt wfdbdesc}, {\tt wfdbwhich}, @@ -4915,7 +4915,7 @@ at the resolution of your printer. \htmladdnormallink{{\tt plt}}{../wag/plt-1.htm} is a highly capable plotting package freely available from -\htmladdnormallink{{\tt www.physionet.org};}{http://www.physionet.org/}. +\htmladdnormallink{{\tt physionet.org};}{http://physionet.org/}. \htmladdnormallink{{\tt plot2d}}{../wag/plot2d-1.htm} (included in the WFDB Software Package) is a bare-bones command-line front end to {\tt gnuplot}, a fairly capable @@ -4939,7 +4939,7 @@ Current sources for \WAVE{}, and precompiled \WAVE{} binaries for GNU/Linux or Mac OS X may be obtained from PhysioNet. Point your Web browser to -\htmladdnormallink{{\tt http://www.physionet.org/}}{http://www.physionet.org/} +\htmladdnormallink{{\tt http://physionet.org/}}{http://physionet.org/} for details. Note that \WAVE{} cannot be run at all until the WFDB library (contained within @@ -4959,7 +4959,7 @@ distribution and attempt to port `{\tt cmdtool}' (a simple terminal emulator included in the XView distribution) first. Compared to the original sources, the Linux/Mac OS X/MS-Windows version of XView (freely available from -\htmladdnormallink{PhysioNet}{http://www.physionet.org/physiotools/xview/}, +\htmladdnormallink{PhysioNet}{http://physionet.org/physiotools/xview/}, \htmladdnormallink{{\tt metalab.unc.edu}} {ftp://metalab.unc.edu/pub/Linux/libs/X/xview/}, \htmladdnormallink{{\tt www.rpmfind.net}} {http://www.rpmfind.net/linux/RPM/}, and their mirrors, and @@ -5307,7 +5307,7 @@ linked libraries are missing. Locate these on your system (for example, using a command such as `{\tt find / -name libxview.so.3 -print}'; if any of these libraries cannot be found on your system, it may be -downloaded from \htmladdnormallink{PhysioNet}{http://www.physionet.org/}.) +downloaded from \htmladdnormallink{PhysioNet}{http://physionet.org/}.) Add the directories in which the missing libraries are found to your {\tt LD\_LIBRARY\_PATH}. For example, if the missing libraries are located in {\tt /usr/openwin/lib}, and you are using the C-shell, use the @@ -5455,6 +5455,10 @@ `{\tt xset}', however, remember that this setting lasts only until the server exits and will need to be repeated afterwards. +On some platforms, there are simpler ways to install the missing fonts. See +the \htmladdnormallink{XView}{http://physionet.org/physiotools/xview/} home +page on PhysioNet for pointers. + \section{Display-related questions} \subsection{I can't see the signals!} @@ -5579,7 +5583,7 @@ (this can be done easily using \htmladdnormallink{{\tt xform}}{../wag/xform-1.htm}, \htmladdnormallink{{\tt snip}}{../wag/snip-1.htm}, or a web browser). Check -\htmladdnormallink{PhysioNet}{http://www.physionet.org/} for updates to \WAVE{} +\htmladdnormallink{PhysioNet}{http://physionet.org/} for updates to \WAVE{} or to the WFDB library that may correct this bug. \subsection{How can I get correct display scales?} @@ -6187,7 +6191,7 @@ records. Moreover, since typical block sizes are quite large, the time resolution of annotations in this case is very coarse. A format converter for EDF files, -\htmladdnormallink{{\tt edf2mit}}{http://www.physionet.org/}, may be +\htmladdnormallink{{\tt edf2mit}}{http://physionet.org/}, may be used to rewrite such files in a format that \WAVE{} can read without these limitations. This converter also constructs a suitable header file from the embedded header in the EDF file. @@ -6452,7 +6456,7 @@ If you need to develop your own applications for use with \WAVE{}, read the \htmladdnormallink{{\it WFDB Programmer's Guide}}{../wpg/wpg.htm}. You may read these guides on-line on-line or print your own copies (visit -\htmladdnormallink{PhysioNet}{http://www.physionet.org/}). +\htmladdnormallink{PhysioNet}{http://physionet.org/}). \index{on-line help}\index{help}\index{Mozilla}\index{web browser} \item @@ -6469,8 +6473,8 @@ if you have installed \WAVE{} 6.0 or later on your system, or to \htmladdnormallink -{{\tt http://www.physio\-net.\-org\-/physiotools\-/wug/}} -{http://www.physionet.org/physiotools/wug/} +{{\tt http://physio\-net.\-org\-/physiotools\-/wug/}} +{http://physionet.org/physiotools/wug/} otherwise). \item diff -Naur --exclude Makefile --exclude info wfdb-10.4.11/install-wave32 wfdb-10.4.12/install-wave32 --- wfdb-10.4.11/install-wave32 2008-11-19 14:38:10.000000000 -0500 +++ wfdb-10.4.12/install-wave32 2009-01-13 14:25:28.000000000 -0500 @@ -1,14 +1,15 @@ #! /bin/sh -# file: install-wave32 G. Moody 7 October 2008 -# +# file: install-wave32 G. Moody 7 October 2008 +# Last revised: 13 January 2009 for Fedora 10 # Build and install WAVE on 64-bit Linux # -# This script has been tested on 64-bit Fedora 9 running on an Intel Core2 -# CPU. The methods used here (but not this script itself) have also been -# tested on 64-bit Fedora 7 and 8 running on both AMD and Intel 64-bit CPUs. -# It requires root (superuser) permissions and must be run from within the -# top-level WFDB source directory (the directory that also contains the -# 'configure' script). +# This script has been tested on 64-bit Fedora 10 running on an Intel Core2 +# CPU. The previous version (find it in the sources for wfdb-10.4.11) was +# tested on 64-bit Fedora 9, also on an Intel Core2 CPU. The methods used here +# (but not this script itself) have also been tested on 64-bit Fedora 7 and 8 +# running on both AMD and Intel 64-bit CPUs. It requires root (superuser) +# permissions and must be run from within the top-level WFDB source directory +# (the directory that also contains the 'configure' script). # # WAVE must be compiled as a 32-bit application, because it depends on the # XView toolkit, which does not support 64-bit mode (and most likely, never @@ -24,11 +25,15 @@ # respective developer's toolkits. The easiest way to install these on # Fedora is using the yum commands below. These packages may have different # names in other Linux distributions, and "yum" itself may not be available -# as a package manager in some distributions. These commands are safe to run -# even if any or all of these packages are already installed. - -yum -y update glibc-devel.i386 libX11-devel.i386 libXpm-devel.i386 libcurl-devel.i386 -yum -y install glibc-devel.i386 libX11-devel.i386 libXpm-devel.i386 libcurl-devel.i386 +# as a package manager in some distributions. These commands are safe to +# run even if any or all of these packages are already installed. +yum -y update libgcc.i386 glibc-devel.i386 libX11-devel.i386 \ + libXpm-devel.i386 libcurl-devel.i386 xorg-x11-fonts-misc +yum -y install libgcc.i386 glibc-devel.i386 libX11-devel.i386 \ + libXpm-devel.i386 libcurl-devel.i386 xorg-x11-fonts-misc +# On Debian-based distributions, such as Ubuntu, it's awkward to force apt-get +# to install 32-bit packages, especially if like-named 64-bit packages have +# been installed already. Google on "getlibs" for an alternative. # 2. XView libraries available from PhysioNet # These are available as RPMs for Fedora and other RPM-based distributions, @@ -36,10 +41,13 @@ # easiest way to install them on Fedora is using the RPM command below. # Again, this command is safe even if any or all of these are already # installed. - rpm -ivh http://physionet.org/physiotools/xview/i386-Fedora/xview-3.2p1.4-21.1.fc8.i386.rpm \ http://physionet.org/physiotools/xview/i386-Fedora/xview-clients-3.2p1.4-21.1.fc8.i386.rpm \ http://physionet.org/physiotools/xview/i386-Fedora/xview-devel-3.2p1.4-21.1.fc8.i386.rpm +# +# On Debian or Ubuntu, simply run +# apt-get install xviewg-dev +# instead of the rpm commands above (32-bit XView is in the Debian repositories). # 3. the 32-bit version of the WFDB library # This is easily compiled and installed by the following commands: diff -Naur --exclude Makefile --exclude info wfdb-10.4.11/lib/annot.c wfdb-10.4.12/lib/annot.c --- wfdb-10.4.11/lib/annot.c 2008-04-18 14:35:15.000000000 -0400 +++ wfdb-10.4.12/lib/annot.c 2009-01-20 15:07:58.000000000 -0500 @@ -1,10 +1,10 @@ /* file: annot.c G. Moody 13 April 1989 - Last revised: 18 April 2008 wfdblib 10.4.7 + Last revised: 20 January 2009 wfdblib 10.4.12 WFDB library functions for annotations _______________________________________________________________________________ wfdb: a library for reading and writing annotated waveforms (time series data) -Copyright (C) 1989-2008 George B. Moody +Copyright (C) 1989-2009 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 @@ -86,6 +86,10 @@ must be written in time order; simultaneous annotations must be written in `chan' order. Simultaneous annotations are readable but not writable by earlier versions. + +Beginning in version 10.4.12, the canonical annotation order is given by +the time, num, and chan fields in that order. Thus simultaneous annotations +may be attached to the same signal provided that their num fields are unique. */ #include "wfdblib.h" @@ -108,6 +112,8 @@ #define CHN ((unsigned)(62 << CS)) /* change 'chan' field */ #define AUX ((unsigned)(63 << CS)) /* auxiliary information */ +#define AUXBUFLEN 520 + /* Constants for AHA annotation files only */ #define ABLKSIZ 1024 /* AHA annotation file block length */ #define AUXLEN 6 /* length of AHA aux field */ @@ -124,7 +130,7 @@ WFDB_Frequency afreq; /* time resolution, in ticks/second */ unsigned word; /* next word from the input file */ int ateof; /* EOF-reached indicator */ - char auxstr[1+255+1]; /* aux string buffer (byte count+data+null) */ + char auxstr[AUXBUFLEN]; /* aux string buffer */ unsigned index; /* next available position in auxstr */ double tmul, ptmul; /* tmul * annotation time = sample count */ WFDB_Time tt; /* annotation time (MIT format only). This @@ -144,8 +150,8 @@ int seqno; /* annotation serial number (AHA format only)*/ char *rname; /* record with which annotator is associated */ char out_of_order; /* if >0, one or more annotations written by - putann are not in the canonical (time, chan) - order */ + putann are not in the canonical (time, num, + chan) order */ } **oad; static WFDB_Frequency oafreq; /* time resolution in ticks/sec for newly- created output annotators */ @@ -167,7 +173,12 @@ if (*(annot.aux+1) == '#') { if (strncmp(annot.aux + 1, "## time resolution: ", 20) == 0) { sscanf(annot.aux + 20, "%lf", &(iad[i]->afreq)); - if (iad[i]->afreq) iad[i]->tmul = getifreq()/iad[i]->afreq; + if (iad[i]->afreq) { + WFDB_Frequency sf = getifreq(); + + if (sf > 0.) + iad[i]->tmul = sf/iad[i]->afreq; + } } continue; } @@ -189,7 +200,14 @@ if (annot.time != 0L || annot.anntyp != NOTE || annot.subtyp != 0 || annot.aux == NULL) { if (iad[i]->tmul) annot.time /= iad[i]->tmul; - iad[i]->tmul = (iad[i]->afreq) ? getifreq()/iad[i]->afreq : getspf(); + if (iad[i]->afreq) { + WFDB_Frequency sf = getifreq(); + + if (sf > 0.) + iad[i]->tmul = sf/iad[i]->afreq; + } + else + iad[i]->tmul = getspf(); annot.time = (WFDB_Time)(annot.time * iad[i]->tmul + 0.5); (void)ungetann(i, &annot); } @@ -228,7 +246,7 @@ if (putann(i, &annot) < 0) return (-1); } - if (oafreq != oad[i]->afreq) { + if (oafreq != oad[i]->afreq && oafreq > 0.) { (void)sprintf(buf+1, "## time resolution: %g", oafreq); buf[0] = strlen(buf+1); oad[i]->afreq = oafreq; @@ -451,7 +469,7 @@ case NUM: ia->ann.num = DATA & ia->word; break; case AUX: /* auxiliary information */ len = ia->word & 0377; /* length of auxiliary data */ - if (ia->index >= 256 - len) + if (ia->index >= AUXBUFLEN-2 - len) ia->index = 0; /* buffer index */ ia->ann.aux = ia->auxstr + ia->index; /* save pointer */ ia->auxstr[ia->index++] = len; /* save length byte */ @@ -540,7 +558,7 @@ return (-2); } t = annot->time; - if (oa->ann.time == (WFDB_Time)0 && oafreq != oa->afreq) { + if (oa->ann.time == (WFDB_Time)0 && oafreq != oa->afreq && oafreq > 0.) { static WFDB_Annotation tra; char buf[30]; @@ -554,11 +572,10 @@ tra.aux = NULL; if (putann(n, &tra) < 0) return (-1); } - if (((delta = t - oa->ann.time) < 0L || - (delta == 0L && annot->chan <= oa->ann.chan)) && - (t != 0L || oa->ann.time != 0L)) { - oa->out_of_order = 1; - } + delta = t - oa->ann.time; + if (!(annot->chan > oa->ann.chan || annot->num > oa->ann.num || delta>0L || + (t == 0L && oa->ann.time == 0L))) + oa->out_of_order = 1; switch (oa->info.stat) { case WFDB_WRITE: /* MIT-format output file */ default: diff -Naur --exclude Makefile --exclude info wfdb-10.4.11/lib/signal.c wfdb-10.4.12/lib/signal.c --- wfdb-10.4.11/lib/signal.c 2008-10-27 15:01:01.000000000 -0400 +++ wfdb-10.4.12/lib/signal.c 2009-01-16 13:09:20.000000000 -0500 @@ -1,5 +1,5 @@ /* file: signal.c G. Moody 13 April 1989 - Last revised: 27 October 2008 wfdblib 10.4.10 + Last revised: 27 October 2008 wfdblib 10.4.12 WFDB library functions for signals _______________________________________________________________________________ @@ -55,6 +55,7 @@ isigopen (opens input signals) osigopen (opens output signals) osigfopen (opens output signals by name) + findsig [10.4.12] (find an input signal with a specified name) getspf [9.6] (returns number of samples returned by getvec per frame) setgvmode [9.0](sets getvec operating mode) setifreq [10.2.6](sets the getvec sampling frequency) @@ -1464,8 +1465,9 @@ WFDB_Signal s; unsigned int b, d = 1, n, nn; - /* Do nothing if the input pointer is correct already. */ - if (istime == (in_msrec ? t + segp->samp0 : t)) + /* 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)) return (0); /* Find the first signal that belongs to group g. */ @@ -2171,6 +2173,32 @@ return (nosig); } +/* Function findsig finds an open input signal with the name specified by its +(string) argument, and returns the associated signal number. If the argument +is a decimal numeral and is less than the number of open input signals, it is +assumed to represent a signal number, which is returned. Otherwise, findsig +looks for a signal with a description matching the string, and returns the +first match if any, or -1 if not. */ + +int findsig(char *p) +{ + char *q = p; + int s; + + while ('0' <= *q && *q <= '9') + q++; + if (*q == 0) { /* all digits, probably a signal number */ + s = atoi(p); + if (s < nisig) 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. */ + for (s = 0; s < nisig; s++) + if ((q = isd[s]->info.desc) && strcmp(p, q) == 0) return (s); + /* No match found. */ + return (-1); +} + /* Function getvec can operate in two different modes when reading multifrequency records. In WFDB_LOWRES mode, getvec returns one sample of each signal per frame (decimating any oversampled signal by returning the average of @@ -2231,9 +2259,14 @@ FINT setifreq(WFDB_Frequency f) { - if (f > 0.0) { - WFDB_Frequency error, g = sfreq; + WFDB_Frequency error, g = sfreq; + if (g <= 0.0) { + ifreq = 0.0; + wfdb_error("setifreq: no open input record\n"); + return (-1); + } + if (f > 0.0) { SREALLOC(gv0, nisig, sizeof(WFDB_Sample)); SREALLOC(gv1, nisig, sizeof(WFDB_Sample)); setafreq(ifreq = f); diff -Naur --exclude Makefile --exclude info wfdb-10.4.11/lib/wfdb.h wfdb-10.4.12/lib/wfdb.h --- wfdb-10.4.11/lib/wfdb.h 2008-11-19 21:03:17.000000000 -0500 +++ wfdb-10.4.12/lib/wfdb.h 2009-01-20 23:15:10.000000000 -0500 @@ -1,10 +1,10 @@ /* file: wfdb.h G. Moody 13 June 1983 - Last revised: 14 July 2008 wfdblib 10.4.7 + Last revised: 19 January 2009 wfdblib 10.4.12 WFDB library type, constant, structure, and function interface definitions _______________________________________________________________________________ wfdb: a library for reading and writing annotated waveforms (time series data) -Copyright (C) 1983-2008 George B. Moody +Copyright (C) 1983-2009 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 @@ -33,7 +33,7 @@ /* WFDB library version. */ #define WFDB_MAJOR 10 #define WFDB_MINOR 4 -#define WFDB_RELEASE 11 +#define WFDB_RELEASE 12 #define WFDB_NETFILES 1 /* if 1, library includes code for HTTP, FTP clients */ #define WFDB_NETFILES_LIBCURL 1 @@ -176,9 +176,9 @@ the beginning of the record */ char anntyp; /* annotation type (< ACMAX, see */ signed char subtyp; /* annotation subtype */ - signed char chan; /* channel number */ + unsigned char chan; /* channel number */ signed char num; /* annotator number */ - char *aux; /* pointer to auxiliary information */ + unsigned char *aux; /* pointer to auxiliary information */ }; /* Composite data types */ diff -Naur --exclude Makefile --exclude info wfdb-10.4.11/lib/wfdb.h0 wfdb-10.4.12/lib/wfdb.h0 --- wfdb-10.4.11/lib/wfdb.h0 2008-07-14 12:20:15.000000000 -0400 +++ wfdb-10.4.12/lib/wfdb.h0 2009-01-19 16:24:37.000000000 -0500 @@ -1,10 +1,10 @@ /* file: wfdb.h G. Moody 13 June 1983 - Last revised: 14 July 2008 wfdblib 10.4.7 + Last revised: 19 January 2009 wfdblib 10.4.12 WFDB library type, constant, structure, and function interface definitions _______________________________________________________________________________ wfdb: a library for reading and writing annotated waveforms (time series data) -Copyright (C) 1983-2008 George B. Moody +Copyright (C) 1983-2009 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 @@ -176,9 +176,9 @@ the beginning of the record */ char anntyp; /* annotation type (< ACMAX, see */ signed char subtyp; /* annotation subtype */ - signed char chan; /* channel number */ + unsigned char chan; /* channel number */ signed char num; /* annotator number */ - char *aux; /* pointer to auxiliary information */ + unsigned char *aux; /* pointer to auxiliary information */ }; /* Composite data types */ diff -Naur --exclude Makefile --exclude info wfdb-10.4.11/NEWS wfdb-10.4.12/NEWS --- wfdb-10.4.11/NEWS 2008-11-19 22:53:40.000000000 -0500 +++ wfdb-10.4.12/NEWS 2009-01-20 23:49:17.000000000 -0500 @@ -1,3 +1,45 @@ +10.4.12: + The rule for sorting annotations within a file has been changed to + allow a much larger number of simultaneous annotations (i.e., + annotations in a given annotation file with identical 'time' fields) + than was previously possible. Since version 6.1, the WFDB library + sorts simultaneous annotations according to the value of their 'chan' + fields, allowing for 256 simultaneous annotations at any given time. + Beginning in version 10.4.12, the library sorts simultaneous + annotations according to their 'num' fields, then sorts those with + identical 'num' fields according to their 'chan' fields, allowing up to + 65,536 simultaneous annotations at any given time. + + A new WFDB library function, findsig(), returns the signal number + of the input signal matching its string argument, or -1 if no such + input signal exists. If the string argument could be interpreted + as an input signal number, it is taken as such; otherwise, the + string argument must be an exact match to a signal name ("desc" + field in the siginfo structure). + + WFDB applications calsig, pschart, psfd, rdsamp, sqrs, + sqrs125, wabp, wqrs, and xform now accept signal names in any + context in which an input signal number can be given. + + The install-wave32 script now installs 32-bit libgcc and Open Look + glyph fonts if they are missing, as by default in Fedora 10. + + Previous versions of WFDB library function setifreq() entered an + infinite loop if invoked (contrary to specifications) before + opening an input record. setifreq() now detects the error, emits + an appropriate warning, and returns. + + If a WFDB application that uses WFDB library version 10.4.5 + through 10.4.11 attempted to read an annotation file before + reading the sampling frequency of the associated record (for + example, by invoking isigopen() or sampfreq()), the annotation + times might all appear to be zero. This may occur when + reading annotations created using WFDB 10.4.5 or later. The + times supplied when creating the file are correctly written + but may be incorrectly read in these cases. This problem was + corrected in this release; thanks to Thomas Heldt for + reporting it and providing a reproducible example of it. + 10.4.11: Build process improvements, especially on Cygwin and MinGW targets.