diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/app/fir.c wfdb-10.4.0/app/fir.c --- wfdb-10.3.17/app/fir.c 2002-11-14 17:17:46.000000000 -0500 +++ wfdb-10.4.0/app/fir.c 2006-02-25 21:58:44.000000000 -0500 @@ -1,9 +1,9 @@ /* file: fir.c G. Moody 5 January 1987 - Last revised: 14 November 2002 + Last revised: 25 February 2006 ------------------------------------------------------------------------------- fir: General-purpose FIR filter for database records -Copyright (C) 2002 George B. Moody +Copyright (C) 1987-2006 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 @@ -77,10 +77,11 @@ int argc; char *argv[]; { - char *irec = "16", *orec = "16"; + char *irec = "16", *orec = "16", *p; double *tc = NULL, atof(); int i, n = 128, s; long from = 0L, shift = 0L, to = 0L; + static int gvmode = 0; static WFDB_Siginfo *chin, *chout; FILE *ifile; @@ -125,6 +126,9 @@ help(); exit(0); break; + case 'H': /* operate in WFDB_HIGHRES mode */ + gvmode = WFDB_HIGHRES; + break; case 'i': /* input record name */ if (++i >= argc) { (void)fprintf(stderr, "%s: record name must follow -i\n", @@ -190,6 +194,11 @@ help(); exit(1); } + + if (gvmode == 0 && (p = getenv("WFDBGVMODE"))) + gvmode = atoi(p); + setgvmode(gvmode|WFDB_GVPAD); + if ((nsig = isigopen(irec, NULL, 0)) <= 0) exit(2); if ((chin = malloc(nsig * sizeof(WFDB_Siginfo))) == NULL || @@ -281,6 +290,7 @@ " -C file filter using coefficients read from the specified FILE", " -f TIME begin at specified time", " -h print this usage summary", + " -H read multifrequency signals in high resolution mode", " -i IREC read signals from record IREC (default: 16)", " -n NREC create a header file, using record name NREC and signal", " descriptions from IREC", diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/app/Makefile.tpl wfdb-10.4.0/app/Makefile.tpl --- wfdb-10.3.17/app/Makefile.tpl 2005-06-08 17:03:51.000000000 -0400 +++ wfdb-10.4.0/app/Makefile.tpl 2005-09-09 11:17:04.000000000 -0400 @@ -1,10 +1,10 @@ # file: Makefile.tpl G. Moody 23 May 2000 -# Last revised: 8 June 2005 +# Last revised: 9 September 2005 # This section of the Makefile should not need to be changed. CFILES = ann2rr.c bxb.c calsig.c ecgeval.c epicmp.c fir.c ihr.c mfilt.c \ mrgann.c mxm.c nguess.c nst.c plotstm.c pscgen.c pschart.c psfd.c rdann.c \ - rdsamp.c rr2ann.c rxr.c sampfreq.c sample.c sigamp.c sigavg.c skewedit.c \ + rdsamp.c rr2ann.c rxr.c sampfreq.c sigamp.c sigavg.c skewedit.c \ snip.c sortann.c sqrs.c sqrs125.c sumann.c sumstats.c tach.c time2sec.c \ wabp.c wfdbcat.c wfdbcollate.c wfdbdesc.c \ wfdbwhich.c wqrs.c wrann.c wrsamp.c xform.c diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/app/mfilt.c wfdb-10.4.0/app/mfilt.c --- wfdb-10.3.17/app/mfilt.c 2002-11-14 17:18:42.000000000 -0500 +++ wfdb-10.4.0/app/mfilt.c 2006-02-25 22:06:31.000000000 -0500 @@ -1,9 +1,9 @@ /* file: mfilt.c G. Moody 27 June 1993 - Last revised: 14 November 2002 + Last revised: 25 February 2006 ------------------------------------------------------------------------------- mfilt: General-purpose median filter for database records -Copyright (C) 2002 George B. Moody +Copyright (C) 1993-2006 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 @@ -100,8 +100,9 @@ int argc; char *argv[]; { - char *irec = "16", *ofname, *orec = "16"; + char *irec = "16", *ofname, *orec = "16", *p; int format, i; + static int gvmode = 0; static WFDB_Siginfo *si, *so; pname = prog_name(argv[0]); @@ -118,6 +119,9 @@ help(); exit(0); break; + case 'H': /* operate in WFDB_HIGHRES mode */ + gvmode = WFDB_HIGHRES; + break; case 'i': /* input record name */ if (++i >= argc) { (void)fprintf(stderr, "%s: record name must follow -i\n", @@ -174,6 +178,10 @@ } median = flen/2; + if (gvmode == 0 && (p = getenv("WFDBGVMODE"))) + gvmode = atoi(p); + setgvmode(gvmode|WFDB_GVPAD); + if ((nsig = isigopen(irec, NULL, 0)) <= 0) exit(2); if ((si = (WFDB_Siginfo *)malloc(nsig * sizeof(WFDB_Siginfo))) == NULL || @@ -249,6 +257,7 @@ "and OPTIONS may include:", " -f TIME begin at specified time", " -h print this usage summary", + " -H read multifrequency signals in high resolution mode", " -i IREC read signals from record IREC (default: 16)", " -n NREC create a header file, using record name NREC and signal", " specifications from IREC", diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/app/nst.c wfdb-10.4.0/app/nst.c --- wfdb-10.3.17/app/nst.c 2002-11-14 17:25:20.000000000 -0500 +++ wfdb-10.4.0/app/nst.c 2006-02-25 20:35:59.000000000 -0500 @@ -1,9 +1,8 @@ /* file: nst.c G. Moody 8 December 1983 - Last revised: 14 November 2002 - + Last revised: 25 February 2006 ------------------------------------------------------------------------------- nst: Noise stress test -Copyright (C) 2002 George B. Moody +Copyright (C) 1983-2006 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 @@ -494,14 +493,23 @@ errct++; /* Adjust offsets to avoid discontinuities. */ for (i = 0; i < nisig; i++) - z[i] = vin[i] + gn[i]*vin[nse[i]] - vout[i]; + if (vin[i] != WFDB_INVALID_SAMPLE && + vin[nse[i]] != WFDB_INVALID_SAMPLE && + vout[i] != WFDB_INVALID_SAMPLE) + z[i] = vin[i] + gn[i]*vin[nse[i]] - vout[i]; } else if (getvec(vin) < 0) errct++; for (i = 0; i < nisig; i++) { - vin[i] -= zz[i]; /* remove any offset first */ - vout[i] = vin[i] + gn[i]*vin[nse[i]] - z[i]; + if (vin[i] != WFDB_INVALID_SAMPLE && + vin[nse[i]] != WFDB_INVALID_SAMPLE && + vout[i] != WFDB_INVALID_SAMPLE) { + vin[i] -= zz[i]; /* remove any offset first */ + vout[i] = vin[i] + gn[i]*vin[nse[i]] - z[i]; + } + else + vout[i] = WFDB_INVALID_SAMPLE; } if (putvec(vout) < 0) errct++; diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/app/sigamp.c wfdb-10.4.0/app/sigamp.c --- wfdb-10.3.17/app/sigamp.c 2002-11-14 17:30:48.000000000 -0500 +++ wfdb-10.4.0/app/sigamp.c 2006-02-25 22:00:46.000000000 -0500 @@ -1,9 +1,9 @@ /* file: sigamp.c G. Moody 30 November 1991 - Last revised: 14 November 2002 + Last revised: 25 February 2006 ------------------------------------------------------------------------------- sigamp: Measure signal amplitudes -Copyright (C) 2002 George B. Moody +Copyright (C) 1991-2006 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 @@ -50,9 +50,10 @@ int argc; char *argv[]; { - char *record = NULL, *prog_name(); + char *p, *record = NULL, *prog_name(); int i, j, jlow, jhigh, nmax = NMAX, ampcmp(), getptp(), getrms(); long from = 0L, to = 0L, t; + static int gvmode = 0; static WFDB_Siginfo *si; static WFDB_Anninfo ai; void help(); @@ -91,6 +92,9 @@ help(); exit(0); break; + case 'H': /* operate in WFDB_HIGHRES mode */ + gvmode = WFDB_HIGHRES; + break; case 'n': if (++i >= argc) { (void)fprintf(stderr, @@ -149,6 +153,11 @@ help(); exit(1); } + + if (gvmode == 0 && (p = getenv("WFDBGVMODE"))) + gvmode = atoi(p); + setgvmode(gvmode|WFDB_GVPAD); + if ((nsig = isigopen(record, NULL, 0)) <= 0) exit(2); if ((si = malloc(nsig * sizeof(WFDB_Siginfo))) == NULL || (v0 = malloc(nsig * sizeof(int))) == NULL || @@ -371,6 +380,7 @@ " DT2 = 0.05 (seconds after annotation)", " -f TIME begin at specified time", " -h print this usage summary", + " -H read multifrequency signals in high resolution mode", " -n NMAX make up to NMAX measurements per signal (default: 300)", /* default NMAX is defined as 300 above */ " -p print results in physical units (default: ADC units)", diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/app/sqrs125.c wfdb-10.4.0/app/sqrs125.c --- wfdb-10.3.17/app/sqrs125.c 2002-11-14 17:34:51.000000000 -0500 +++ wfdb-10.4.0/app/sqrs125.c 2006-02-25 22:02:19.000000000 -0500 @@ -1,9 +1,9 @@ /* file: sqrs125.c G. Moody 27 October 1990 - Last revised: 14 November 2002 + Last revised: 25 February 2006 ------------------------------------------------------------------------------- sqrs125: Single-channel QRS detector for data sampled at 100 - 150 Hz -Copyright (C) 2002 George B. Moody +Copyright (C) 1990-2006 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 @@ -89,7 +89,7 @@ int argc; char *argv[]; { - char *record = NULL, *prog_name(); + char *p, *record = NULL, *prog_name(); int filter, i, minutes = 0, nsig, time = 0, slopecrit, sign, maxslope = 0, nslope = 0, qtime, maxtime, t0, t1, t2, t3, t4, t5, @@ -97,6 +97,7 @@ long from = 0L, next_minute, now, spm, to = 0L; WFDB_Anninfo a; WFDB_Annotation annot; + static int gvmode = 0; static WFDB_Siginfo *s; void help(); @@ -115,6 +116,9 @@ help(); exit(0); break; + case 'H': /* operate in WFDB_HIGHRES mode */ + gvmode = WFDB_HIGHRES; + break; case 'm': /* threshold */ if (++i >= argc) { (void)fprintf(stderr, "%s: threshold must follow -m\n", pname); @@ -161,6 +165,10 @@ exit(1); } + if (gvmode == 0 && (p = getenv("WFDBGVMODE"))) + gvmode = atoi(p); + setgvmode(gvmode|WFDB_GVPAD); + if ((nsig = isigopen(record, NULL, 0)) < 1) exit(2); if ((s = malloc(nsig * sizeof(WFDB_Siginfo))) == NULL || (v = malloc(nsig * sizeof(WFDB_Sample))) == NULL) { @@ -280,6 +288,7 @@ "include any of:", " -f TIME begin at specified time", " -h print this usage summary", + " -H read multifrequency signals in high resolution mode", " -m THRESH set detector threshold to THRESH (default: 250)", " -s SIGNAL analyze specified signal (default: 0)", " -t TIME stop at specified time", diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/app/sqrs.c wfdb-10.4.0/app/sqrs.c --- wfdb-10.3.17/app/sqrs.c 2002-11-14 18:57:50.000000000 -0500 +++ wfdb-10.4.0/app/sqrs.c 2006-02-25 22:01:16.000000000 -0500 @@ -1,9 +1,9 @@ /* file: sqrs.c G. Moody 27 October 1990 - Last revised: 14 November 2002 + Last revised: 25 February 2006 ------------------------------------------------------------------------------- sqrs: Single-channel QRS detector -Copyright (C) 2002 George B. Moody +Copyright (C) 1990-2006 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 @@ -41,7 +41,7 @@ This program is provided as an example only, and is not intended for any clinical application. At the time the algorithm was originally published, its performance was typical of state-of-the-art QRS detectors. Recent designs, -particularly those which can analyze two or more input signals, may exhibit +particularly those that can analyze two or more input signals, may exhibit significantly better performance. Usage: @@ -81,7 +81,7 @@ int argc; char *argv[]; { - char *record = NULL, *prog_name(); + char *p, *record = NULL, *prog_name(); int filter, i, minutes = 0, nsig, time = 0, slopecrit, sign, maxslope = 0, nslope = 0, qtime, maxtime, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, @@ -89,6 +89,7 @@ long from = 0L, next_minute, now, spm, to = 0L; WFDB_Anninfo a; WFDB_Annotation annot; + static int gvmode = 0; static WFDB_Siginfo *s; void help(); @@ -107,6 +108,9 @@ help(); exit(0); break; + case 'H': /* operate in WFDB_HIGHRES mode */ + gvmode = WFDB_HIGHRES; + break; case 'm': /* threshold */ if (++i >= argc) { (void)fprintf(stderr, "%s: threshold must follow -m\n", pname); @@ -153,6 +157,10 @@ exit(1); } + if (gvmode == 0 && (p = getenv("WFDBGVMODE"))) + gvmode = atoi(p); + setgvmode(gvmode|WFDB_GVPAD); + if ((nsig = isigopen(record, NULL, 0)) < 1) exit(2); if ((s = malloc(nsig * sizeof(WFDB_Siginfo))) == NULL || (v = malloc(nsig * sizeof(WFDB_Sample))) == NULL) { @@ -274,6 +282,7 @@ "include any of:", " -f TIME begin at specified time", " -h print this usage summary", + " -H read multifrequency signals in high resolution mode", " -m THRESH set detector threshold to THRESH (default: 500)", " -s SIGNAL analyze specified signal (default: 0)", " -t TIME stop at specified time", diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/app/wabp.c wfdb-10.4.0/app/wabp.c --- wfdb-10.3.17/app/wabp.c 2005-05-11 12:40:31.000000000 -0400 +++ wfdb-10.4.0/app/wabp.c 2006-02-25 22:18:08.000000000 -0500 @@ -1,8 +1,8 @@ -/* file wabp.c Wei Zong 23 October 1998 - Last revised: 11 May 2005 (by G. Moody) +/* file wabp.c Wei Zong 23 October 1998 + Last revised: 25 February 2006 (by G. Moody) ----------------------------------------------------------------------------- wabp: beat detector for arterial blood presure (ABP) signal -Copyright (C) 2002-2005 Wei Zong +Copyright (C) 1998-2006 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 @@ -127,7 +127,8 @@ WFDB_Sample *v; WFDB_Siginfo *s; WFDB_Time from = 0L, next_minute, now, spm, t, tj, tpq, to = 0L, tt, t1; - char *prog_name(); + char *p, *prog_name(); + static int gvmode = 0; void help(); pname = prog_name(argv[0]); @@ -148,6 +149,9 @@ help(); exit(0); break; + case 'H': /* operate in WFDB_HIGHRES mode */ + gvmode = WFDB_HIGHRES; + break; case 'm': /* threshold */ if (++i >= argc || (Tm = atoi(argv[i])) <= 0) { (void)fprintf(stderr, "%s: threshold ( > 0) must follow -m\n", @@ -200,6 +204,10 @@ exit(1); } + if (gvmode == 0 && (p = getenv("WFDBGVMODE"))) + gvmode = atoi(p); + setgvmode(gvmode|WFDB_GVPAD); + if ((nsig = isigopen(record, NULL, 0)) < 1) exit(2); if ((s = (WFDB_Siginfo *)malloc(nsig * sizeof(WFDB_Siginfo))) == NULL) { (void)fprintf(stderr, "%s: insufficient memory\n", pname); @@ -394,6 +402,7 @@ " do not annotate", " -f TIME begin at specified time (default: beginning of the record)", " -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)", " -t TIME stop at specified time (default: end of the record)", diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/app/wqrs.c wfdb-10.4.0/app/wqrs.c --- wfdb-10.3.17/app/wqrs.c 2005-05-11 12:40:46.000000000 -0400 +++ wfdb-10.4.0/app/wqrs.c 2006-02-25 22:03:25.000000000 -0500 @@ -1,8 +1,8 @@ /* file: wqrs.c Wei Zong 23 October 1998 - Last revised: 11 May 2005 (by G. Moody) + Last revised: 25 February 2006 (by G. Moody) ----------------------------------------------------------------------------- wqrs: Single-lead QRS detector based on length transform -Copyright (C) 1998-2005 Wei Zong +Copyright (C) 1998-2006 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 @@ -71,7 +71,7 @@ #include #include -#define BUFLN 4096 /* must be a power of 2, see ltsamp() */ +#define BUFLN 16384 /* must be a power of 2, see ltsamp() */ #define EYE_CLS 0.25 /* eye-closing period is set to 0.25 sec (250 ms) */ #define LPERIOD 1000 /* learning period is the first LPERIOD samples */ #define MaxQRSw 0.13 /* maximum QRS width (130ms) */ @@ -94,7 +94,7 @@ Since this program analyzes only one signal, ltsamp() does not have an input argument for specifying a signal number; rather, it always filters and returns samples from the signal designated by the global variable - 'signal'. The caller must never "rewind" by more than BUFLN samples (the + 'sig'. The caller must never "rewind" by more than BUFLN samples (the length of ltsamp()'s buffers). */ WFDB_Sample ltsamp(WFDB_Time t) @@ -124,11 +124,14 @@ } while (t > tt) { static int aet = 0, et; + WFDB_Sample v0, v1, v2; Yn2 = Yn1; Yn1 = Yn; - Yn = 2*Yn1 - Yn2 + sample(sig, tt) - - 2*sample(sig, tt-LPn) + sample(sig, tt-LP2n); + if ((v0 = sample(sig, tt)) != WFDB_INVALID_SAMPLE && + (v1 = sample(sig, tt-LPn)) != WFDB_INVALID_SAMPLE && + (v2 = sample(sig, tt-LP2n)) != WFDB_INVALID_SAMPLE) + Yn = 2*Yn1 - Yn2 + v0 - 2*v1 + v2; dy = (Yn - Yn1) / LP2n; /* lowpass derivative of input */ et = ebuf[(++tt)&(BUFLN-1)] = sqrt(lfsc +dy*dy); /* length transform */ lbuf[(tt)&(BUFLN-1)] = aet += et - ebuf[(tt-LTwindow)&(BUFLN-1)]; @@ -140,6 +143,7 @@ main(int argc, char **argv) { + char *p; char *record = NULL; /* input record name */ float sps; /* sampling frequency, in Hz (SR) */ float samplingInterval; /* sampling interval, in milliseconds */ @@ -154,13 +158,14 @@ the threshold is automatically reduced to a minimum value; the threshold is restored upon a detection */ - int Ta, T0; /* high and low detection thresholds */ + double Ta, T0; /* high and low detection thresholds */ WFDB_Anninfo a; WFDB_Annotation annot; WFDB_Gain gain; WFDB_Sample *v; WFDB_Siginfo *s; WFDB_Time from = 0L, next_minute, now, spm, t, tj, tpq, to = 0L, tt, t1; + static int gvmode = 0; char *prog_name(); void help(); @@ -182,6 +187,9 @@ help(); exit(0); break; + case 'H': /* operate in WFDB_HIGHRES mode */ + gvmode = WFDB_HIGHRES; + break; case 'j': /* annotate J-points (ends of QRS complexes) */ jflag = 1; break; @@ -245,6 +253,10 @@ exit(1); } + if (gvmode == 0 && (p = getenv("WFDBGVMODE"))) + gvmode = atoi(p); + setgvmode(gvmode|WFDB_GVPAD); + if ((nsig = isigopen(record, NULL, 0)) < 1) exit(2); if ((s = (WFDB_Siginfo *)malloc(nsig * sizeof(WFDB_Siginfo))) == NULL) { (void)fprintf(stderr, "%s: insufficient memory\n", pname); @@ -267,6 +279,8 @@ if ((to = strtim(argv[to])) < 0L) to = -to; } + else + to = strtim("e"); annot.subtyp = annot.num = 0; annot.chan = sig; @@ -286,7 +300,7 @@ (void)sample(sig, 0L); if (dflag) { - for (t = from; (to == 0L || t < to) && sample_valid(); t++) + for (t = from; t < to || (to == 0L && sample_valid()); t++) printf("%6d\t%6d\n", sample(sig, t), ltsamp(t)); exit(0); } @@ -311,19 +325,23 @@ } /* Average the first 8 seconds of the length-transformed samples - to determine the initial thresholds Ta and T0 */ - t1 = from + strtim("8"); + to determine the initial thresholds Ta and T0. The number of samples + in the average is limited to half of the ltsamp buffer if the sampling + frequency exceeds about 2 KHz. */ + if ((t1 = strtim("8")) > BUFLN*0.9) + t1 = BUFLN/2; + t1 += from; for (T0 = 0, t = from; t < t1 && sample_valid(); t++) T0 += ltsamp(t); T0 /= t1 - from; Ta = 3 * T0; /* Main loop */ - for (t = from; (to == 0L || t < to) && sample_valid(); t++) { + for (t = from; t < to || (to == 0L && sample_valid()); t++) { static int learning = 1, T1; if (learning) { - if (t > from + LPERIOD) { + if (t > t1) { learning = 0; T1 = T0; t = from; /* start over */ @@ -454,6 +472,7 @@ " do not annotate", " -f TIME begin at specified time (default: beginning of the record)", " -h print this usage summary", + " -H read multifrequency signals in high resolution mode", " -j find and annotate J-points (QRS ends) as well as QRS onsets", " -m THRESH set detector threshold to THRESH (default: 100)", /* TmDEF */ " -p FREQ specify power line (mains) frequency (default: 60)", diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/app/xform.c wfdb-10.4.0/app/xform.c --- wfdb-10.3.17/app/xform.c 2005-08-12 00:25:02.000000000 -0400 +++ wfdb-10.4.0/app/xform.c 2005-11-20 15:35:52.000000000 -0500 @@ -1,9 +1,9 @@ /* file: xform.c G. Moody 8 December 1983 - Last revised: 13 April 2004 + Last revised: 20 November 2005 ------------------------------------------------------------------------------- xform: Sampling frequency, amplitude, and format conversion for WFDB records -Copyright (C) 1983-2004 George B. Moody +Copyright (C) 1983-2005 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 @@ -703,8 +703,14 @@ n = ofreq/f; mn = m*n; (void)getvec(vin); - for (i = 0; i < nosig; i++) - vv[i] = vin[siglist[i]]*gain[i] + deltav[i]; + for (i = 0; i < nosig; i++) { + WFDB_Sample v = vin[siglist[i]]; + + if (v != WFDB_INVALID_SAMPLE) + vv[i] = v*gain[i] + deltav[i]; + else + vv[i] = WFDB_INVALID_SAMPLE; + } } /* If in multifrequency mode, set msiglist offsets. */ diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/checkpkg/libcheck wfdb-10.4.0/checkpkg/libcheck --- wfdb-10.3.17/checkpkg/libcheck 2005-08-11 11:44:53.000000000 -0400 +++ wfdb-10.4.0/checkpkg/libcheck 2006-02-27 11:53:43.000000000 -0500 @@ -1,6 +1,6 @@ #!/bin/sh # file: libcheck G. Moody 8 September 2001 -# Last revised: 11 August 2005 +# Last revised: 27 February 2006 # # This script checks the functionality of the WFDB library by comparing the # outputs of 'lcheck' with expected outputs. See 'lcheck.c' for details of @@ -22,6 +22,10 @@ exit fi +# If WFDB was set by the user, unset it for the duration of this test so +# that we have a known WFDB path. +unset WFDB + case $# in 0) VERBOSE=0 ;; *) VERBOSE=1 ;; diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/checkpkg/Makefile.tpl wfdb-10.4.0/checkpkg/Makefile.tpl --- wfdb-10.3.17/checkpkg/Makefile.tpl 2005-08-04 21:25:10.000000000 -0400 +++ wfdb-10.4.0/checkpkg/Makefile.tpl 2006-03-02 10:12:13.000000000 -0500 @@ -1,7 +1,8 @@ all: @rm -f lcheck @make lcheck - @./libcheck $(DBDIR) $(LIBDIR) + -@./libcheck $(DBDIR) $(LIBDIR) + @../conf/prompt "Press to test applications:"; read A @./appcheck $(INCDIR) $(BINDIR) $(LIBDIR) lcheck: lcheck.c diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/conf/solaris.def wfdb-10.4.0/conf/solaris.def --- wfdb-10.3.17/conf/solaris.def 2005-08-07 10:52:14.000000000 -0400 +++ wfdb-10.4.0/conf/solaris.def 2006-02-21 13:46:24.000000000 -0500 @@ -81,7 +81,7 @@ # use -g and -O simultaneously. MFLAGS is gcc-specific. # CFLAGS = -O $(CCDEFS) $(LC) -I$(INCDIR) # `gcc' users may comment out the previous line, and uncomment the next one. -CFLAGS = $(MFLAGS) -g -O $(CCDEFS)`$(LC) -I$(INCDIR) +CFLAGS = $(MFLAGS) -g -O $(CCDEFS) $(LC) -I$(INCDIR) # LDFLAGS is appended to the C compiler command line to specify loading the # WFDB library. diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/conf/version.def wfdb-10.4.0/conf/version.def --- wfdb-10.3.17/conf/version.def 2005-06-27 15:02:29.000000000 -0400 +++ wfdb-10.4.0/conf/version.def 2006-02-23 15:44:05.000000000 -0500 @@ -1,10 +1,10 @@ # file: version.def G. Moody 24 May 2000 -# Last revised: 11 June 2005 +# Last revised: 23 February 2006 # Each release of the WFDB Software Package is identified by a three-part # version number, defined here: MAJOR = 10 -MINOR = 3 -RELEASE = 17 +MINOR = 4 +RELEASE = 0 VERSION = $(MAJOR).$(MINOR).$(RELEASE) # RPMRELEASE can be incremented if changes are made between official diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/doc/Makefile.tpl wfdb-10.4.0/doc/Makefile.tpl --- wfdb-10.3.17/doc/Makefile.tpl 2003-03-19 12:48:56.000000000 -0500 +++ wfdb-10.4.0/doc/Makefile.tpl 2006-03-02 12:46:37.000000000 -0500 @@ -1,5 +1,5 @@ # file: Makefile.tpl G. Moody 24 May 2000 -# Last revised: 24 February 2003 +# Last revised: 2 March 2006 # Change the settings below as appropriate for your setup. # Set COLORS to 'color' if you have a color printer and would like to print @@ -208,4 +208,4 @@ cd wag-src; make clean cd wpg-src; make clean cd wug-src; make clean - rm -f index.htm index.html wag/* wpg/* wug/* *~ + rm -f index.htm index.html wag/* wpg/*.htm* wpg/*.pdf wug/*.ps wpg/info/w* wug/* *~ diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/doc/README wfdb-10.4.0/doc/README --- wfdb-10.3.17/doc/README 2002-06-24 09:59:40.000000000 -0400 +++ wfdb-10.4.0/doc/README 2006-02-26 23:17:18.000000000 -0500 @@ -1,5 +1,5 @@ file: README G. Moody 7 September 1989 - Last revised: 24 June 2002 + Last revised: 26 February 2006 This directory and its subdirectories contain documentation for the WFDB Software Package, including UNIX man pages in troff source format for the WFDB @@ -53,6 +53,11 @@ /usr/bin/pstoimg with the version found in wug-src/wave/misc and try again. These problems occur under Red Hat Linux 7.1, 7.2, and 7.3. +Under Fedora Core 4, most of the software needed to create the formatted +documentation is standard; if 'yum' is correctly configured, you can install +latex2html and texi2html if they are missing using the command (as root): + yum install latex2html texi2html + The following files will be found in this directory: Makefile UNIX `make' description file for printing the WFDB software diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/doc/wag-src/dfa.1 wfdb-10.4.0/doc/wag-src/dfa.1 --- wfdb-10.3.17/doc/wag-src/dfa.1 2002-10-28 17:28:19.000000000 -0500 +++ wfdb-10.4.0/doc/wag-src/dfa.1 2002-10-28 17:28:19.000000000 -0500 @@ -77,7 +77,7 @@ \fBdfa\fR is available as part of PhysioToolkit under the GPL (see \fBSOURCE\fR below). .SH AUTHORS -JE Mietus (joe at physionet dot org), C-K Peng, and GB Moody, based on C-K Peng's +JE Mietus (joe@physionet.org), C-K Peng, and GB Moody, based on C-K Peng's original Fortran implementation. .SH SOURCE http://www.physionet.org/physiotools/dfa/dfa.c diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/doc/wag-src/fir.1 wfdb-10.4.0/doc/wag-src/fir.1 --- wfdb-10.3.17/doc/wag-src/fir.1 2002-07-28 10:48:58.000000000 -0400 +++ wfdb-10.4.0/doc/wag-src/fir.1 2006-02-25 22:22:12.000000000 -0500 @@ -1,4 +1,4 @@ -.TH FIR 1 "28 July 2002" "WFDB 10.2.7" "WFDB Applications Guide" +.TH FIR 1 "25 February 2006" "WFDB 10.4.0" "WFDB Applications Guide" .SH NAME fir \- general-purpose FIR filter for WFDB records .SH SYNOPSIS @@ -23,6 +23,13 @@ \fB-h\fR Print a usage summary. .TP +\fB-H\fR +Read the signal files in high-resolution mode (default: standard mode). +These modes are identical for ordinary records. For multifrequency records, +the standard decimation of oversampled signals to the frame rate is suppressed +in high-resolution mode (rather, all other signals are resampled at the highest +sampling frequency). +.TP \fB-i\fR \fIrecord\fR Use the specified \fIrecord\fR for input (default: record 16). .TP diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/doc/wag-src/header.5 wfdb-10.4.0/doc/wag-src/header.5 --- wfdb-10.3.17/doc/wag-src/header.5 2002-10-28 17:37:30.000000000 -0500 +++ wfdb-10.4.0/doc/wag-src/header.5 2005-10-19 17:35:34.000000000 -0400 @@ -1,4 +1,4 @@ -.TH HEADER 5 "1 August 2002" "WFDB software 10.2.7" "WFDB Applications Guide" +.TH HEADER 5 "5 August 2005" "WFDB software 10.3.18" "WFDB Applications Guide" .SH NAME header \- WFDB header file format .SH DESCRIPTION @@ -18,7 +18,8 @@ Header files for ordinary records (those that contain one segment) also contain a \fIsignal specification line\fP for each signal. Header files for multi-segment records (supported by WFDB library version 9.1 and later versions) -contain a \fIsegment specification line\fP for each segment. +contain a \fIsegment specification line\fP for each segment; see the section +on multi-segment records below for details. .LP \fIComment lines\fP may appear anywhere in a header file. The first printing character in a comment line must be `#'. Comment lines that follow @@ -276,15 +277,24 @@ fields is not considered to be part of the description, however. If the description is missing, the WFDB library functions that read header files supply a description of the +.SS "Info strings" +.LP +Comment lines that follow the last signal specification line +in a header file can be read and written by the WFDB library functions +\fIgetinfo\fP and \fIputinfo\fP; the contents of these lines (excluding +the initial `#' comment character) are referred to as `info strings'. +There must be no whitespace preceding the initial `#' in any line that +is to be recognized by \fIgetinfo\fP. form ``record \fIxxx\fP, signal \fIn\fP''. -.SS "Segment specification lines" +.SS "Multi-segment records" .LP -Each non-empty, non-comment line following the record line in a -multi-segment record contains specifications for one segment, -beginning with segment 0. Header files must contain valid segment -specification lines for at least as many segments as were indicated -in the record line. Any extra segment specification lines are not -read by WFDB library functions. +Each non-empty, non-comment line following the record line in the +top-level header file of a multi-segment record contains specifications +for one segment, beginning with segment 0. (Info strings cannot be used in +the top-level header file of a multi-segment record.) Top-level header +files must contain valid segment specification lines for at least as +many segments as were indicated in the record line. Any extra segment +specification lines are not read by WFDB library functions. .LP A \fIsegment\fP is simply an ordinary (single-segment) record, with its own header and signal files. By including segments in a @@ -294,17 +304,33 @@ the applications to do anything special to move from one segment to another. The only restrictions are that segments cannot themselves contain other segments (they \fImust\fP be single-segment records), +the sampling frequencies must not change from segment to segment, and the number of samples per signal must be defined for each segment -in the record line of the segment's own header file. In addition, the -number of signals and the sampling frequency should match in all -segments of a record, and it is best if the signal gain, baseline, -units, ADC resolution and zero, and description match for -corresponding signals in all segments (these recommendations are not -enforced by the WFDB library, but existing applications are likely to +in the record line of the segment's own header file. +.LP +Two types of multi-segment records are defined. In a \fIfixed-layout\fR +record, the arrangement of signals is constant across all segments, and +the signal gain, baseline, units, ADC resolution and zero, and description +match for corresponding signals in all segments (these recommendations are +not enforced by the WFDB library, but existing applications are likely to behave unpredictably if they are not followed). Note, however, that it is not necessary to use the same signal storage format in all segments, and significant space savings may be possible in some cases by selecting -an optimal format for each segment. +an optimal format for each segment. Each segment of a fixed-layout record +is an ordinary record containing one or more samples. +.LP +In a \fIvariable-layout\fR record, the arrangement of signals may vary, +signals may be absent in some segments, and the gains and baselines may +change between segments. A variable-layout record can be identified by +the presence of a \fIlayout segment\fR, which must be segment 0 and must +have a length of 0 samples. The layout segment has no associated signal +files; its header file specifies the desired arrangement of signals and +their gains and baselines. Signal file names in a layout segment header +are recorded as `~'. When read using WFDB library version 10.3.17 +or later, the signals of a variable layout record are rearranged, shifted, +and rescaled as needed in order to present the signals in the arrangement +and with the gains and baselines specified in the layout segment header. +.SS "Segment specification lines" .LP Each segment specification line contains the following fields, separated by whitespace: @@ -317,14 +343,13 @@ \fInumber of samples per signal\fP This number must match the number specified in the header file for the single-segment record that comprises the segment. -.SS "Info strings" .LP -Comment lines that follow the last signal specification line -in a header file can be read and written by the WFDB library functions -\fIgetinfo\fP and \fIputinfo\fP; the contents of these lines (excluding -the initial `#' comment character) are referred to as `info strings'. -There must be no whitespace preceding the initial `#' in any line that -is to be recognized by \fIgetinfo\fP. +Variable-layout records may contain \fInull segments\fR, which can be +identified if the record name given in the segment specification line is +`~'. The number of samples per signal indicates the length of the null +segment; when read, these samples have the value WFDB_INVALID_DATA +(defined in ). Null segments do not have associated header +or signal files. .SS "Examples:" .TP \fIExample 1 (MIT DB record 100):\fP diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/doc/wag-src/lwcat.1 wfdb-10.4.0/doc/wag-src/lwcat.1 --- wfdb-10.3.17/doc/wag-src/lwcat.1 2003-05-01 14:50:40.000000000 -0400 +++ wfdb-10.4.0/doc/wag-src/lwcat.1 2006-03-02 12:27:02.000000000 -0500 @@ -95,8 +95,8 @@ \fB-golden\fR Plot in a 7.5x4.635 inch (191x118 mm) window, 0.5 inches (12.7 mm) from the left edge and 3.365 inches (85 mm) from the bottom edge of the page -(the aspect ratio is approximately the "golden ratio", (1+sqrt(5))/2 = 1.61803 -...). +(the aspect ratio is approximately the "golden ratio", +(1+sqrt(5))/2 = 1.61803 ...). .PP Other window options can be easily added; see the source for \fBlwcat\fR for details. diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/doc/wag-src/Makefile.tpl wfdb-10.4.0/doc/wag-src/Makefile.tpl --- wfdb-10.3.17/doc/wag-src/Makefile.tpl 2005-06-12 01:09:31.000000000 -0400 +++ wfdb-10.4.0/doc/wag-src/Makefile.tpl 2006-02-27 00:19:07.000000000 -0500 @@ -1,5 +1,5 @@ # file: Makefile.tpl G. Moody 24 May 2000 -# Last revised: 9 April 2003 +# Last revised: 27 February 2006 # Change the settings below as appropriate for your setup. # D2PARGS is a list of options for dvips. Uncomment one of these to set the @@ -74,7 +74,9 @@ # wag0.ps, and takes longer to render as a result. To enable creation of # PostScript with DSCs in this way, uncomment the next two lines: WAGPSREQ = wag.pdf -MAKEWAGPS = acroread -toPostScript -level1 -fast wag.pdf +# The latest versions of acroread no longer support the -level1 and -fast +# options used in previous versions of this Makefile (level 2 is the default). +MAKEWAGPS = acroread -toPostScript wag.pdf # You can use pdftops instead of acroread by commenting out the previous line # and uncommenting the next one. # MAKEWAGPS = pdftops wag.pdf diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/doc/wag-src/memse.1 wfdb-10.4.0/doc/wag-src/memse.1 --- wfdb-10.3.17/doc/wag-src/memse.1 2003-06-16 14:39:23.000000000 -0400 +++ wfdb-10.4.0/doc/wag-src/memse.1 2006-02-26 22:55:59.000000000 -0500 @@ -1,4 +1,4 @@ -.TH MEMSE 1 "16 June 2003" "WFDB 10.3.8" "WFDB Applications Guide" +.TH MEMSE 1 "26 February 2006" "WFDB 10.4.0" "WFDB Applications Guide" .SH NAME memse \- estimate power spectrum using maximum entropy (all poles) method .SH SYNOPSIS @@ -43,6 +43,12 @@ .PP \fIOptions\fR are: .TP +\fB-b\fR \fIlow high\fR [ \fIlow high ...\fR ] +Print power in the specified bands. Each \fIlow\fR and \fIhigh\fR pair +specifies the low and high frequency boundaries of the band of interest, +in Hz. Multiple bands may be specified following a single \fB-b\fR option; +only the last \fB-b\fR option has any effect. Also see \fB-s\fR below. +.TP \fB-f\fR \fIfrequency\fR Show the center frequency for each bin in the first column. The \fIfrequency\fR argument specifies the input sampling frequency; the center @@ -67,6 +73,9 @@ \fB-P\fR Generate a power spectrum (print squared magnitudes). .TP +\fB-s\fR +Print power in a standard set of frequency bands of interest for HRV analysis. +.TP \fB-w\fR \fIwindow-type\fR Apply the specified window to the input data. \fIwindow-type\fR may be one of: `Bartlett', `Blackman', `Blackman-Harris', `Hamming', `Hanning', diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/doc/wag-src/mfilt.1 wfdb-10.4.0/doc/wag-src/mfilt.1 --- wfdb-10.3.17/doc/wag-src/mfilt.1 2002-07-30 15:37:25.000000000 -0400 +++ wfdb-10.4.0/doc/wag-src/mfilt.1 2006-02-25 22:22:44.000000000 -0500 @@ -1,4 +1,4 @@ -.TH MFILT 1 "30 July 2002" "WFDB 10.2.7" "WFDB Applications Guide" +.TH MFILT 1 "25 February 2006" "WFDB 10.4.0" "WFDB Applications Guide" .SH NAME mfilt \- general-purpose median filter for WFDB records .SH SYNOPSIS @@ -22,6 +22,13 @@ \fB-h\fR Print a usage summary. .TP +\fB-H\fR +Read the signal files in high-resolution mode (default: standard mode). +These modes are identical for ordinary records. For multifrequency records, +the standard decimation of oversampled signals to the frame rate is suppressed +in high-resolution mode (rather, all other signals are resampled at the highest +sampling frequency). +.TP \fB-i\fR \fIrecord\fR Use the specified \fIrecord\fR for input (default: record 16). .TP diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/doc/wag-src/pschart.1 wfdb-10.4.0/doc/wag-src/pschart.1 --- wfdb-10.3.17/doc/wag-src/pschart.1 2002-08-06 14:54:47.000000000 -0400 +++ wfdb-10.4.0/doc/wag-src/pschart.1 2005-12-02 10:12:43.000000000 -0500 @@ -1,4 +1,4 @@ -.TH PSCHART 1 "6 August 2002" "WFDB 10.2.7" "WFDB Applications Guide" +.TH PSCHART 1 "2 September 2005" "WFDB 10.3.18" "WFDB Applications Guide" .SH NAME pschart \- produce annotated `chart recordings' on a PostScript device .SH SYNOPSIS @@ -292,13 +292,12 @@ string in the argument list of a command, so that \fB-a ""\fR, \fB-c ""\fR, and \fB-T ""\fR do not work as described above. Type a space between the quotation marks to avoid this bug, or use one of the UNIX shells that have been ported to -MS-DOS instead of \fBcommand.com\fR.. +MS-DOS instead of \fBcommand.com\fR. .PP There are too many options. Invoke \fBpschart\fR with no arguments for a brief summary of options. .SH SEE ALSO -\fBpsfd\fR(1), \fBsetwfdb\fR(1), \fBview\fR(1), \fBwave\fR(1), \fBwview\fR(1), -\fBxform\fR(1) +\fBpsfd\fR(1), \fBsetwfdb\fR(1), \fBwave\fR(1), \fBxform\fR(1) .SH AUTHOR George B. Moody (george@mit.edu) .SH SOURCES diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/doc/wag-src/psfd.1 wfdb-10.4.0/doc/wag-src/psfd.1 --- wfdb-10.3.17/doc/wag-src/psfd.1 2005-07-26 15:04:37.000000000 -0400 +++ wfdb-10.4.0/doc/wag-src/psfd.1 2005-09-02 22:07:53.000000000 -0400 @@ -1,4 +1,4 @@ -.TH PSFD 1 "26 July 2005" "WFDB 10.3.5" "WFDB Applications Guide" +.TH PSFD 1 "2 September 2005" "WFDB 10.3.18" "WFDB Applications Guide" .SH NAME psfd \- produce annotated `full-disclosure' plots on a PostScript device .SH SYNOPSIS @@ -275,8 +275,7 @@ There are too many options. Invoke \fBpsfd\fR with no arguments for a brief summary of options. .SH SEE ALSO -\fBpschart\fR(1), \fBsetwfdb\fR(1), \fBview\fR(1), \fBwave\fR(1), -\fBwview\fR(1) +\fBpschart\fR(1), \fBsetwfdb\fR(1), \fBwave\fR(1) .SH AUTHOR George B. Moody (george@mit.edu) .SH SOURCES diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/doc/wag-src/sigamp.1 wfdb-10.4.0/doc/wag-src/sigamp.1 --- wfdb-10.3.17/doc/wag-src/sigamp.1 2002-11-25 23:51:37.000000000 -0500 +++ wfdb-10.4.0/doc/wag-src/sigamp.1 2006-02-25 22:23:55.000000000 -0500 @@ -1,4 +1,4 @@ -.TH SIGAMP 1 "25 November 2002" "WFDB 10.3.0" "WFDB Applications Guide" +.TH SIGAMP 1 "25 February 2006" "WFDB 10.4.0" "WFDB Applications Guide" .SH NAME sigamp \- measure signal amplitudes of a WFDB record .SH SYNOPSIS @@ -30,6 +30,13 @@ \fB-h\fR Print a usage summary. .TP +\fB-H\fR +Read the signal files in high-resolution mode (default: standard mode). +These modes are identical for ordinary records. For multifrequency records, +the standard decimation of oversampled signals to the frame rate is suppressed +in high-resolution mode (rather, all other signals are resampled at the highest +sampling frequency). +.TP \fB-n\fR \fInmax\fR Make up to \fInmax\fR measurements on each signal (default: 300). .TP diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/doc/wag-src/signal.5 wfdb-10.4.0/doc/wag-src/signal.5 --- wfdb-10.3.17/doc/wag-src/signal.5 2002-10-28 17:37:20.000000000 -0500 +++ wfdb-10.4.0/doc/wag-src/signal.5 2005-09-02 22:11:36.000000000 -0400 @@ -1,4 +1,4 @@ -.TH SIGNAL 5 "1 August 2002" "WFDB software 10.2.7" "WFDB Applications Guide" +.TH SIGNAL 5 "2 September 2005" "WFDB software 10.3.18" "WFDB Applications Guide" .SH NAME signal \- WFDB signal file formats .SH DESCRIPTION @@ -15,10 +15,9 @@ represented in 8 bits are represented instead by the largest difference of the appropriate sign (-128 or +127), and subsequent differences are adjusted such that the correct amplitude is obtained as quickly as -possible. Thus the samples read from a format 8 file may not always -be identical to those read from an equivalent format 16 file. -On-line signal files on magnetic disk are often kept in format 8 to save -space. Note that the first differences stored in multiplexed format 8 +possible. Thus there may be loss of information if signals in another +of the formats listed below are converted to format 8. +Note that the first differences stored in multiplexed format 8 files are always determined by subtraction of successive samples from the same signal (otherwise signals with baselines which differ by 128 units or more could not be represented this way). @@ -27,9 +26,9 @@ Each sample is represented by a 16-bit two's complement amplitude stored least significant byte first. Any unused high-order bits are sign-extended from the most significant bit. -The format used for MIT\-BIH and AHA database distribution 9-track tapes -is format 16, with the addition of a logical EOF (octal 0100000) and -null-padding after the logical EOF. +Historically, the format used for MIT\-BIH and AHA database distribution +9-track tapes was format 16, with the addition of a logical EOF (octal 0100000) +and null-padding after the logical EOF. .SS Format 61 .PP Each sample is represented by a 16-bit two's complement amplitude stored @@ -53,8 +52,7 @@ 4 remaining bits of the first byte pair (which are the 4 high bits of the 12-bit sample) and the next byte (which contains the remaining 8 bits of the second sample). The process is repeated for each successive pair of samples. -Most of the signal files on the second edition of the MIT\-BIH Arrhythmia -Database CD-ROM are format 212 files. +Most of the signal files in PhysioBank are written in format 212. .SS Format 310 .PP Each sample is represented by a 10-bit two's-complement amplitude. The first diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/doc/wag-src/sqrs.1 wfdb-10.4.0/doc/wag-src/sqrs.1 --- wfdb-10.3.17/doc/wag-src/sqrs.1 2002-11-22 15:11:19.000000000 -0500 +++ wfdb-10.4.0/doc/wag-src/sqrs.1 2006-02-25 22:25:00.000000000 -0500 @@ -1,4 +1,4 @@ -.TH SQRS 1 "22 November 2002" "WFDB 10.3.0" "WFDB Applications Guide" +.TH SQRS 1 "25 February 2006" "WFDB 10.4.0" "WFDB Applications Guide" .SH NAME sqrs, sqrs125 \- single-channel QRS detector .SH SYNOPSIS @@ -49,6 +49,16 @@ Begin at the specified \fItime\fR in \fIrecord\fR (default: the beginning of \fIrecord\fR). .TP +\fB-h\fR +Print a usage summary. +.TP +\fB-H\fR +Read the signal files in high-resolution mode (default: standard mode). +These modes are identical for ordinary records. For multifrequency records, +the standard decimation of oversampled signals to the frame rate is suppressed +in high-resolution mode (rather, all other signals are resampled at the highest +sampling frequency). +.TP \fB-m\fR \fIthreshold\fR Specify the detection \fIthreshold\fR (default: 500 units); use higher values to reduce false detections, or lower values to reduce the number of missed diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/doc/wag-src/wabp.1 wfdb-10.4.0/doc/wag-src/wabp.1 --- wfdb-10.3.17/doc/wag-src/wabp.1 2002-12-05 03:32:47.000000000 -0500 +++ wfdb-10.4.0/doc/wag-src/wabp.1 2006-02-25 22:25:42.000000000 -0500 @@ -1,4 +1,4 @@ -.TH WABP 1 "5 December 2002" "WFDB 10.3.1" "WFDB Applications Guide" +.TH WABP 1 "25 February 2006" "WFDB 10.4.0" "WFDB Applications Guide" .SH NAME wabp \- arterial blood pressure (ABP) pulse detector .SH SYNOPSIS @@ -37,6 +37,13 @@ \fB-h\fR Print a brief usage summary. .TP +\fB-H\fR +Read the signal files in high-resolution mode (default: standard mode). +These modes are identical for ordinary records. For multifrequency records, +the standard decimation of oversampled signals to the frame rate is suppressed +in high-resolution mode (rather, all other signals are resampled at the highest +sampling frequency). +.TP \fB-R\fR Resample the input at 125 Hz (default: do not resample). .TP diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/doc/wag-src/wag.ht0 wfdb-10.4.0/doc/wag-src/wag.ht0 --- wfdb-10.3.17/doc/wag-src/wag.ht0 2005-06-13 03:09:37.000000000 -0400 +++ wfdb-10.4.0/doc/wag-src/wag.ht0 2006-02-27 11:11:35.000000000 -0500 @@ -20,7 +20,7 @@ George B. Moody
Harvard-MIT Division of Health Sciences and Technology

-Copyright ©1980-2005 George B. Moody +Copyright ©1980-2006 George B. Moody

The most recent versions of the programs described in this guide may be freely downloaded from PhysioNet. For diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/doc/wag-src/wave.1 wfdb-10.4.0/doc/wag-src/wave.1 --- wfdb-10.3.17/doc/wag-src/wave.1 2005-06-13 02:35:24.000000000 -0400 +++ wfdb-10.4.0/doc/wag-src/wave.1 2005-09-02 22:03:59.000000000 -0400 @@ -1,5 +1,5 @@ '\" t -.TH WAVE 1 "13 June 2005" "WFDB 10.3.16" "WFDB Applications Guide" +.TH WAVE 1 "2 September 2005" "WFDB 10.3.18" "WFDB Applications Guide" .SH NAME wave \- waveform analyzer, viewer, and editor .SH SYNOPSIS @@ -176,8 +176,9 @@ .PP You can control many aspects of \fBwave\fR's appearance and behavior by setting its resources. If you are not familiar with this concept, refer to an -introductory book on using the X Window System, such as Quercia and O'Reilly's -`X Window System User's Guide'. Since \fBwave\fR is built using the XView +introductory book on using the X Window System, such as Darwin, Quercia, and +O'Reilly's \fIX User's Guide: Open Look Edition\fR (see the link below). +Since \fBwave\fR is built using the XView toolkit, all of the resources listed in \fBxview\fR(7) can be used with \fBwave\fR. In addition, the following \fBwave\fR-specific resources may also be set: @@ -651,19 +652,20 @@ quit confirmation) and any unsaved edits may be lost. This problem is the result of a bug in the XView \fItermsw\fR package used for the Analysis Commands window. To avoid this bug, always run \fBwave\fR in -the background under SunOS. The Solaris 2.x and Linux versions of the -XView library do not have this bug. +the background under SunOS. The Linux, Mac OS X, MS Windows, and +Solaris 2.x versions of the XView library do not have this bug. .PP If \fBwave\fR opens with an empty signal window, this may mean that -the X server's backing store is disabled. \fBwave\fR versions 6.8 and later -incorporate a workaround that avoids this problem. If you must use an earlier -version of \fBwave\fR, enable backing -store and restart the X server. (Using XFree86 4.x, backing store can -be enabled by inserting the line `Option "backingstore"' in the -`Device' section(s) of the \fBXF86Config-4\fR file. If the X server is -normally started by a display manager such as \fBxdm\fR, close all windows -and restart the server with \fI\fR. Otherwise, log out, -log in, and restart the X server manually if necessary.) +the X server's backing store is disabled. \fBwave\fR versions 6.8 and +later incorporate a workaround that avoids this problem. If you must +use an earlier version of \fBwave\fR, enable backing store and restart +the X server. (Using the X servers from the x.org or XFree86 +projects, backing store can be enabled by inserting the line `Option +"backingstore"' in the `Device' section(s) of the \fBxorg.conf\fR or +\fBXF86Config-4\fR file. If your X server is normally started by a +display manager such as \fBxdm\fR, close all windows and restart the +server with \fI\fR. Otherwise, log out, log in, +and restart the X server manually if necessary.) .PP If this doesn't solve the problem, use any of \fBwave\fR's navigation controls, or resize the signal window, to make the signals visible. On @@ -690,9 +692,12 @@ XView application has run at least once since the X server was started. .SH SEE ALSO -\fBpschart\fR(1), \fBview\fR(1), \fBwview\fR(1), \fBxview\fR(7) +\fBpschart\fR(1), \fBxview\fR(7) .br -\fIWAVE User's Guide\fR +\fIWAVE User's Guide\fR (http://www.physionet.org/physiotools/wug/) +.br +\fIX Window System User's Guide: Open Look Edition\fR +(http://www.oreilly.com/openbook/openlook/) .SH AVAILABILITY .PP \fBwave\fR currently runs under FreeBSD, GNU/Linux, Mac OS X, MS-Windows with @@ -702,7 +707,7 @@ you will need to port XView to your system first (or purchase a commercial port if one is available). Sources for XView are available from PhysioNet (\fBwww.physionet.org\fR, where the sources for \fBwave\fR itself -are also available), \fBmetalab.unc.edu\fR, \fBtsx-11.mit.edu\fR, and their +are also available), \fBwww.ibiblio.org\fR, and their mirrors. \fIWe cannot offer assistance in porting XView; if you wish to try this, you are on your own.\fR If you successfully port the \fBcmdtool\fR terminal emulator application included in the XView sources, we will diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/doc/wag-src/wfdbf.3 wfdb-10.4.0/doc/wag-src/wfdbf.3 --- wfdb-10.3.17/doc/wag-src/wfdbf.3 2003-04-07 15:04:32.000000000 -0400 +++ wfdb-10.4.0/doc/wag-src/wfdbf.3 2006-03-02 12:27:40.000000000 -0500 @@ -1,4 +1,4 @@ -.TH WFDBF 3 "7 April 2003" "WFDB software 10.3.6" "WFDB Applications Guide" +.TH WFDBF 3 "25 February 2006" "WFDB 10.4.0" "WFDB Applications Guide" .SH NAME wfdbf \- Waveform Database library wrappers for Fortran .SH SYNOPSIS @@ -181,7 +181,9 @@ (the language of the WFDB library) require the use of a set of wrappers as an interface between the library and Fortran code that invokes its functions. These wrappers are contained within 'wfdbf.c', provided in -the 'fortran' directory of the WFDB software package. +the 'fortran' directory of the WFDB software package. When the WFDB Software +Package is installed, a copy of 'wfdbf.c' is placed in the same directory +as 'wfdb.h' (normally, /usr/include/wfdb). .PP Most of these wrapper subroutines behave like their similarly-named @@ -204,12 +206,17 @@ .PP To use these wrappers, call them as shown above, then compile your code together with wfdbf.c and link to the WFDB library. If you are -using the GNU g77 compiler, do so using a command such as: +using the GNU g77 compiler (recommended), do so using a command such as: .br - \fBg77 -o foo -fwritable-strings foo.f wfdbf.c -lwfdb\fR + \fBg77 -o foo foo.f -DFIXSTRINGS /usr/include/wfdb/wfdbf.c -lwfdb\fR .br -See 'fortran/README' for further information about using the WFDB Fortran -wrappers. +The wrappers include optionally compiled code that converts traditional +space-terminated Fortran strings to null-terminated C strings and vice versa. +This code is compiled if the symbol FIXSTRINGS is defined, as in the g77 +command above. If you use a different Fortran compiler, this code may not be +necessary. See 'fortran/README' for further information about using the +WFDB Fortran wrappers. + .SH SEE ALSO .TP \fIWFDB Programmer's Guide\fR diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/doc/wag-src/wqrs.1 wfdb-10.4.0/doc/wag-src/wqrs.1 --- wfdb-10.3.17/doc/wag-src/wqrs.1 2002-12-05 01:40:31.000000000 -0500 +++ wfdb-10.4.0/doc/wag-src/wqrs.1 2006-02-25 22:26:20.000000000 -0500 @@ -1,4 +1,4 @@ -.TH WQRS 1 "22 November 2002" "WFDB 10.3.0" "WFDB Applications Guide" +.TH WQRS 1 "25 February 2006" "WFDB 10.4.0" "WFDB Applications Guide" .SH NAME wqrs \- single-channel QRS detector based on length transform .SH SYNOPSIS @@ -41,6 +41,13 @@ \fB-h\fR Print a brief usage summary. .TP +\fB-H\fR +Read the signal files in high-resolution mode (default: standard mode). +These modes are identical for ordinary records. For multifrequency records, +the standard decimation of oversampled signals to the frame rate is suppressed +in high-resolution mode (rather, all other signals are resampled at the highest +sampling frequency). +.TP \fB-j\fR Find and annotate J-points (QRS ends) as well as QRS onsets. .TP diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/doc/wpg-src/fixpg.sh wfdb-10.4.0/doc/wpg-src/fixpg.sh --- wfdb-10.3.17/doc/wpg-src/fixpg.sh 2003-01-28 09:57:49.000000000 -0500 +++ wfdb-10.4.0/doc/wpg-src/fixpg.sh 2006-03-02 08:25:30.000000000 -0500 @@ -28,22 +28,10 @@ cd $1 -R=`grep -l "WFDB Programmer's Guide: WFDB path" *.htm` -if [ "x$R" != "x" ]; then ln -s $R database-path.htm -else echo "Can't find database-path.htm" -fi - -R=`grep -l "

Records" *.htm` -if [ "x$R" != "x" ]; then ln -s $R records.htm -else echo "Can't find records.htm" -fi - -R=`grep -l "WFDB Programmer's Guide: strtim" *.htm` -if [ "x$R" != "x" ]; then ln -s $R strtim.htm -else echo "Can't find strtim.htm" -fi - -R=`grep -l "Compiling a Program with the WFDB Library </H2>" *.htm` -if [ "x$R" != "x" ]; then ln -s $R compiling.htm -else echo "Can't find compiling.htm" -fi +for L in database-path.htm records.htm strtim.htm compiling.htm +do + R=`grep -l "link: $L" *.htm` + if [ "x$R" != "x" ]; then ln -s $R $L + else echo "Can't find $L" + fi +done diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/doc/wpg-src/Makefile.tpl wfdb-10.4.0/doc/wpg-src/Makefile.tpl --- wfdb-10.3.17/doc/wpg-src/Makefile.tpl 2005-06-13 03:14:11.000000000 -0400 +++ wfdb-10.4.0/doc/wpg-src/Makefile.tpl 2006-03-02 09:30:41.000000000 -0500 @@ -1,5 +1,5 @@ # file: Makefile.tpl G. Moody 24 May 2000 -# Last revised: 26 October 2002 +# Last revised: 2 March 2006 # Change the settings below as appropriate for your setup. # D2PARGS is a list of options for dvips. Uncomment one of these to set the @@ -93,6 +93,7 @@ wpg.html: wpg.tex cp -p wpg.tex ../wpg cd ../wpg; texi2html -short_ext -menu -split_node wpg.tex + cd ../wpg; if [ -d wpg ]; then mv wpg/* .; rmdir wpg; fi mv ../wpg/wpg.htm ../wpg/wpg_btoc.htm # use top page as brief TOC rm -f ../wpg/wpg.tex ./fixpg.sh ../wpg diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/doc/wpg-src/wpg0.tex wfdb-10.4.0/doc/wpg-src/wpg0.tex --- wfdb-10.3.17/doc/wpg-src/wpg0.tex 2005-08-20 15:44:31.000000000 -0400 +++ wfdb-10.4.0/doc/wpg-src/wpg0.tex 2006-03-02 14:04:59.000000000 -0500 @@ -21,7 +21,7 @@ @center Harvard-MIT Division of Health Sciences and Technology @page @vskip 0pt plus 1filll -Copyright @copyright{} 1989 -- 2005 George B. Moody +Copyright @copyright{} 1989 -- 2006 George B. Moody @sp 2 The most recent versions of the software described in this guide may be downloaded from @uref{http://www.physionet.org/}. For further @@ -161,6 +161,9 @@ @node Concepts 1, Concepts 2, Overview, Overview @unnumberedsec Records +@html +<!-- link: records.htm --> +@end html @cindex record @cindex record name @cindex tape @@ -489,6 +492,51 @@ WFDB Software Package distribution, for information on any more recent changes that may not be described here. +@unnumberedsubsec Changes in version 10.4.0 + +Version 10.4.0 and later versions of the WFDB library are intended to +be compiled using ANSI/ISO C (and C++) compilers only; previous +versions also supported the use of traditional (K&R) C compilers. The +most obvious change resulting from this decision is in the use of +prototypes in function declarations, an innovation of ANSI C that +permits better error-checking by compilers. The ANSI/ISO C standard is +now more than 15 years old, and it has been over 10 years since a C +compiler that does not support function prototypes was used for +development of the WFDB library. Code in @file{wfdbio.c} that provides +limited support for compilers that do not provide an ANSI/ISO C library +has been retained for now, and @file{wfdb.h} still includes a set of K&R C +function declarations; both of these features are deprecated, however, +and may be removed in future versions of the WFDB library. Users who +still need to use a K&R C compiler to compile the library itself may +find 'unprotoize' (included in the GNU gcc distribution) to be helpful. + +The mapping of lowest expressible sample values to @code{WFDB_INVALID_SAMPLE} +performed by @code{getframe()} (in @file{lib/signal.c}) did not work properly +for signal formats 80 and 160 (in which samples are recorded as unsigned +integers); this has now been corrected. + +The symbol @code{WFDB_GVPAD} is newly defined in @file{<wfdb/wfdb.h>}. +It may be added to @code{WFDB_HIGHRES} or @code{WFDB_LOWRES} and given +as input to @code{setgvmode()}. +The effect of doing so is that missing samples, and samples recognized +as invalid, are replaced by @code{getframe()}, @code{getvec()}, and +@code{sample()} with the most recently read valid values rather than by +the special value @code{WFDB_INVALID_SAMPLE}. +This behavior allows applications such as digital filters to remain +ignorant of missing data without significant performance penalties. + +@code{sample()} now checks that its signal number input +is valid, and returns @code{WFDB_INVALID_SAMPLE} if not. In previous +versions, @code{sample} returned a sample from signal 0 if the requested +signal was unavailable. + +@code{sample_valid()} now returns -1 in the case of a signal that becomes +unavailable before the end of the record (previous versions returned 1 in this case). + +The FIR filter example (@pxref{Example 7}) now works properly. The +previous version always began processing the input at sample 0, +regardless of start time specified in its argument list. + @unnumberedsubsec Changes in version 10.3.17 This version is the first to support reading variable-layout records @@ -969,7 +1017,7 @@ WFDB_Sample v[2]; WFDB_Siginfo s[2]; - if (isigopen("100s", s, 2) < 1) + if (isigopen("100s", s, 2) < 2) exit(1); for (i = 0; i < 10; i++) @{ if (getvec(v) < 0) @@ -1024,6 +1072,9 @@ @node compiling, other languages, print samples, Usage @comment node-name, next, previous, up @section Compiling a Program with the WFDB Library +@html +<!-- link: compiling.htm --> +@end html @cindex WFDB library (compiling with) @cindex compiling @cindex loader options @@ -1132,6 +1183,11 @@ @node other languages, WFDB path, compiling, Usage @comment node-name, next, previous, up @section Using the WFDB library with other languages + +Bindings and wrappers are available so that programs written in a +number of other programming languages can make use of the WFDB library. + +@unnumberedsubsec C++ bindings @cindex C++ bindings If you prefer to write your applications in C++, you may do so, but note @@ -1150,6 +1206,7 @@ linking C++ programs with C libraries. See your compiler manual for further information. +@unnumberedsubsec Fortran wrappers @cindex Fortran bindings @cindex wrappers for Fortran A set of wrapper functions is also available for those who wish to use the WFDB @@ -1180,12 +1237,12 @@ @noindent To compile this program using @code{g77} (the GNU Fortran compiler), save it as -@file{fsamples.f} in the current directory, copy -@uref{http://www.physionet.org/physiotools/wfdb/fortran/wfdbf.c,@file{wfdbf.c}} +@file{fsamples.f} in the current directory, copy @file{wfdbf.c} (which can be +found in the same directory as @file{wfdb.h}, usually @file{/usr/include/wfdb}) to the current directory, then type: @example -g77 -o fsamples -fwritable-strings fsamples.f wfdbf.c -lwfdb +g77 -o fsamples -DFIXSTRINGS fsamples.f wfdbf.c -lwfdb @end example @noindent @@ -1194,6 +1251,7 @@ @uref{http://www.physionet.org/physiotools/wfdb/fortran/README,fortran/README} in the WFDB Software Package. +@unnumberedsubsec Matlab wrappers @cindex Matlab bindings @cindex Octave bindings @cindex Scilab bindings @@ -1202,10 +1260,20 @@ A set of wrappers for Matlab has been written and contributed by Jonas Carlson. These wrappers (@code{wfdb_tools}) provide access to almost all of the functionality of the WFDB library, including HTTP access to remote data files, -to users of Matlab R13 (but not earlier versions) under GNU/Linux or -MS-Windows; other platforms remain to be tested. The wrappers, together with -examples and a tutorial/reference guide, are available from +to users of Matlab R13 (but not earlier versions) under GNU/Linux, Mac OS X, +and MS-Windows; other platforms remain to be tested. The wrappers, together +with examples and a tutorial/reference guide, are available from @uref{http://www.@-physio@-net.@-org/@-physio@-tools/@-matlab/@-wfdb_tools/}. +Using the @code{wfdb_tools} wrappers, the example program can be written in +Matlab as: + +@example + S = WFDB_isigopen('100s') + DATA = WFDB_getvec(length(S), 10) +@end example + +Note that @code{length(S)} is the number of available signals as determined +by @code{WFDB_isigopen} (which becomes the number of columns in @code{DATA}). It should be possible to write a set of wrapper functions similar to @code{wfdb_tools} for use with Octave (a freely available open-source @@ -1222,9 +1290,117 @@ library in native m-code (contributed by Jose Garcia Moros and Salvador Olmos) at @uref{http://www.@-physio@-net.@-org/@-physio@-tools/@-matlab/}. +@unnumberedsubsec SWIG wrappers for Java, Perl, Python, and other languages +@cindex SWIG wrappers +@cindex Java wrappers +@cindex Perl wrappers +@cindex Python wrappers +@cindex C# wrappers + +Isaac Henry has contributed WFDB wrappers for Java, Perl, and Python, +as well as for .NET languages such as C#, created using the Simplified +Wrapper Interface Generator (SWIG, @uref{http://www.swig.org/}). Using +these wrappers, the example program can be written in any of these languages: + +@b{Java:} + +@example +import wfdb.*; + +public class rdsamp @{ + static @{ + System.loadLibrary("wfdbjava"); + @} + + public static void main(String argv[]) @{ + WFDB_SiginfoArray siarray = new WFDB_SiginfoArray(2); + if (wfdb.isigopen ("100s", siarray.cast(), 2) < 2) + System.exit(1); + WFDB_SampleArray v = new WFDB_SampleArray(2); + for (int i = 0; i < 10; i++) @{ + if (wfdb.getvec(v.cast()) < 0) + break; + System.out.print("\t" + v.getitem(0)); + System.out.print("\t" + v.getitem(1)); + System.out.println(); + @} + @} +@} +@end example + +@b{Perl:} + +@example +package wfdb; +use wfdb; + +$siarray = new wfdb::WFDB_SiginfoArray(2); +if ($nsig = isigopen("100s", $siarray->cast(), 2) < 2) @{ + exit(1); +@} +$v = new wfdb::WFDB_SampleArray(2); +for ($i=0; $i < 10; $i++) @{ + if (getvec($v->cast()) < 0) @{ + exit(2); + @} + print "\t", $v->getitem(0), "\t", $v->getitem(1), "\n"; +@} +@end example + +@b{Python:} + +@example +import wfdb, sys + +def main(argv): + siarray = wfdb.WFDB_SiginfoArray(2) + if wfdb.isigopen("100s", siarray.cast(), 2) < 2: sys.exit(1) + v = wfdb.WFDB_SampleArray(2) + for i in range(0,10): + if wfdb.getvec(v.cast()) > 0: sys.exit(2) + print v[0], + print v[1], + print + +if __name__ == "__main__": + main(sys.argv[1:]) + +@end example + +@b{C#:} + +@example +using System; +using Wfdb; + +public class psamples @{ + static void Main(string[] argv) @{ + WFDB_SiginfoArray siarray = new WFDB_SiginfoArray(2); + if (wfdb.isigopen("100s", siarray.cast(), 2) < 2) + Environment.Exit(1); + WFDB_SampleArray v = new WFDB_SampleArray(2); + for (int i = 0; i < 10; i++) @{ + if (wfdb.getvec(v.cast()) < 0) + break; + Console.Write(v.getitem(0)); + Console.Write(v.getitem(1)); + Console.WriteLine(); + @} + @} +@} +@end example + +All SWIG wrappers for the WFDB library are generated using a single +interface file, @file{wfdb.i}. In principle, this file might be used +to generate wrappers for other programming languages supported by SWIG, +including several versions of LISP, Modula-3, PHP, Ruby, and Tcl. + @node WFDB path, running example, other languages, Usage @comment node-name, next, previous, up @section The Database Path and Other Environment Variables +@html +<!-- link: database-path.htm --> +@end html @cindex database path (setting) @cindex path (database) @cindex directories for WFDB files @@ -2174,6 +2350,17 @@ high-resolution sampling intervals. (Otherwise, @code{WFDB_Time} data are in units of frame intervals.) +Version 10.4 and later versions of the WFDB library support two modes +of handling invalid or missing samples. By default, @code{getframe}, +@code{getvec}, and @code{sample} return the special value +@code{WFDB_INVALID_SAMPLE} in such cases. If @var{mode} is +@w{@code{WFDB_GVPAD} + @code{WFDB_LOWRES}} or +@w{@code{WFDB_GVPAD} + @code{WFDB_HIGHRES}}, +however, these functions replicate the previous +valid sample whenever they encounter an invalid or missing sample, +which may simplify the design of applications such as digital filters. +The constant @code{WFDB_GVPAD} is defined in @file{<wfdb/wfdb.h>}. + @c @group @node getspf, , setgvmode, special input modes @unnumberedsubsec getspf @@ -2725,16 +2912,20 @@ @noindent @strong{Return:} @table @asis -@item @i{n} +@item @i{ n} (from @code{sample}): The value (in raw adus) of sample number @var{t} in open signal @var{s},if successful, or the value of the previous successfully read sample. -@item @t{0} -(from @code{sample_valid}): The most recent value returned by -@code{sample} was invalid -@item @t{1} +@item @t{ 1} (from @code{sample_valid}): The most recent value returned by @code{sample} was valid +@item @t{ 0} +(from @code{sample_valid}): The most recent @var{t} given to @code{sample} +follows the end of the record +@item @t{-1} +(from @code{sample_valid}): The most recent value returned by +@code{sample} was invalid (because signal @var{s} is not available at time +@var{t}) @end table @c @end group @@ -2747,15 +2938,21 @@ is invoked with valid input arguments, the companion function @code{sample_valid} returns 1. -There are three ways in which @code{sample} can be invoked with invalid -input arguments. In each case, @code{sample_valid} returns 0, but -@code{sample} attempts to return a reasonable value. If @var{s} is -invalid, @code{sample} returns the value of signal 0 at the specified -time. If @var{t} is negative, the returned value is that of sample -number zero of the specified signal. If @var{t} specifies a sample -number beyond the end of the record, the returned value is that of the -last valid sample of the specified signal. For an example of the use -of @code{sample} and @code{sample_valid}, @pxref{Example 7}. +The @code{sample_valid} function can be used to check the results of the most +recent invocation of @code{sample}. If @code{sample_valid} returns 1, the +latest value returned by @code{sample} is valid. @code{sample_valid} returns 0 +if @code{sample} has most recently returned a padded value following the end of +the record. This allows code that uses @code{sample} to use the condition +@samp{sample_valid() != 0} (or simply @samp{sample_valid()} to determine if +more samples are available. If @code{sample_valid} returns -1, the most recent +value returned by @code{sample} was @code{WFDB_INVALID_SAMPLE} (because the +requested signal @var{s} was unavailable at the requested time @var{t}). Use +the condition @samp{sample_valid() > 0} to check if the most recent value +returned by @code{sample} is a valid value (e.g., suitable for inclusion in a +running average or similar calculation). + +For an example of the use of @code{sample} and @code{sample_valid}, +@pxref{Example 7}. Be sure to call @code{wfdbquit} before exiting from any program that uses @code{sample}, to be certain that dynamically allocated memory @@ -2959,6 +3156,10 @@ @node timstr and strtim, datstr and strdat, annstr and strann, conversion +@html +<!-- link: strtim.htm --> +@end html + @iftex @sp 2 @end iftex @@ -6362,7 +6563,7 @@ @i{7} @{ @i{8} double *c, one = 1.0, vv, atof(); @i{9} int i, j, nc = argc - 4, nsig; -@i{10} long nsamp, t; +@i{10} WFDB_Time nsamp, t, t0, t1; @i{11} static WFDB_Sample *v; @i{12} static WFDB_Siginfo *s; @i{13} @@ -6387,34 +6588,40 @@ @i{32} v = (WFDB_Sample *)malloc(nsig * sizeof(WFDB_Sample)); @i{33} if (s == NULL || v == NULL) @{ @i{34} fprintf(stderr, "insufficient memory\n"); -@i{35} exit(3); +@i{35} exit(4); @i{36} @} @i{37} if (isigopen(argv[1], s, nsig) != nsig) -@i{38} exit(3); -@i{39} if (isigsettime(strtim(argv[2])) < 0) -@i{40} exit(4); -@i{41} if ((nsamp = strtim(argv[3])) < 1) @{ -@i{42} fprintf(stderr, "%s: inappropriate value for duration\n", -@i{43} argv[0]); -@i{44} exit(5); -@i{45} @} -@i{46} if (osigopen("16l", s, nsig) != nsig) -@i{47} exit(6); -@i{48} -@i{49} (void)sample(0, 0L); -@i{50} for (t = 0; t < nsamp && sample_valid(); t++) @{ -@i{51} for (j = 0; j < nsig; j++) @{ -@i{52} for (i = 0, vv = 0.; i < nc; i++) -@i{53} if (c[i] != 0.) vv += c[i]*sample(j, t+i); -@i{54} v[j] = (int)vv; -@i{55} @} -@i{56} if (putvec(v) < 0) break; -@i{57} @} -@i{58} -@i{59} (void)newheader("out"); -@i{60} wfdbquit(); -@i{61} exit(0); -@i{62} @} +@i{38} exit(5); +@i{39} t0 = strtim(argv[2]); +@i{40} if (t0 < (WFDB_Time)0) t0 = -t0; +@i{41} (void)sample(0, t0); +@i{42} if (!sample_valid()) @{ +@i{43} fprintf(stderr, "%s: inappropriate value for start time\n", +@i{44} argv[0]); +@i{45} exit(6); +@i{46} @} +@i{47} if ((nsamp = strtim(argv[3])) < 1) @{ +@i{48} fprintf(stderr, "%s: inappropriate value for duration\n", +@i{49} argv[0]); +@i{50} exit(7); +@i{51} @} +@i{52} t1 = t0 + nsamp; +@i{53} if (osigopen("16l", s, nsig) != nsig) +@i{54} exit(8); +@i{55} +@i{56} for (t = t0; t < t1 && sample_valid(); t++) @{ +@i{57} for (j = 0; j < nsig; j++) @{ +@i{58} for (i = 0, vv = 0.; i < nc; i++) +@i{59} if (c[i] != 0.) vv += c[i]*sample(j, t+i); +@i{60} v[j] = (WFDB_Sample)vv; +@i{61} @} +@i{62} if (putvec(v) < 0) break; +@i{63} @} +@i{64} +@i{65} (void)newheader("out"); +@i{66} wfdbquit(); +@i{67} exit(0); +@i{68} @} @end example @noindent @@ -6439,39 +6646,47 @@ @item Lines 29--40: The record name is @code{argv[1]}, and the start time is @code{argv[2]}; -if the record can't be opened, or the start time is inappropriate, the -program exits. See the previous example for details on how @code{isigopen} -is used. +if the record can't be opened, the program exits. See the previous example +for details on how @code{isigopen} is used. If the user provides an absolute +start time +@iftex +(@pxref{timstr and strtim, , @code{timstr} and @code{strtim}}), +@end iftex +@ifinfo +(@pxref{timstr and strtim}), +@end ifinfo +the negative value returned by @code{strtim} is converted to a sample number +in line 40. + +@item Lines 41--46: +Here, @code{sample} is invoked only for its side effect; if any samples can +be read from the specified record beginning at sample number @code{t0}, then +@code{sample(0, 0L)} returns a valid sample, so that the value returned by +@code{sample_valid} is true (1). If not, the program exits. -@item Lines 41--45: +@item Lines 47--52: The @var{duration} argument should be a time interval in @var{HH:MM:SS} format; @code{strtim} converts it to the appropriate number of -samples. +samples, and @code{t1} is set to the calculated end time in line 52. -@item Lines 46--47: +@item Lines 53--54: The output signals will be written to files in the current directory according to the specifications for record @file{16l} (@pxref{Piped and Local Records}). If we can't write as many output signals as there are input signals, the program exits. -@item Line 49: -Here, @code{signal} is invoked only for its side effect; assuming that -any samples can be read from the specified record, @code{sample(0, 0L)} -returns a valid sample, so that the value returned by -@code{sample_valid()} is true (1). - -@item Lines 50--57: +@item Lines 56--63: Here's where the work is done. The outer loop is executed once per sample vector, the middle loop once per signal, and the inner loop -once per coefficient. In line 53, we retrieve an input sample, +once per coefficient. In line 59, we retrieve an input sample, multiply it by a filter coefficient, and add it to a running sum. -The sum (@code{vv}) is initialized to zero in line 52 before we begin, and is -converted to an @code{int} in line 54 when we are finished. Once -an entire sample vector has been filtered, it is written out in line 56. -The entire process is repeated up to @code{nsamp} times, or until -we run out of input samples. +The sum (@code{vv}) is initialized to zero in line 58 before we begin, and is +converted to a @code{WFDB_Sample} in line 60 when we are finished. Once +an entire output sample vector ia ready, it is written in line 62. +The entire process is repeated until we reach input sample number @code{t1}, +or we run out of input samples. -@item Line 59: +@item Line 65: The program creates a header file for record @file{out}, using the signal specifications from record @file{16l} and the sampling frequency from the input record. @@ -7779,7 +7994,7 @@ Before beginning the installation of the WFDB Software Package, obtain and install the @code{libcurl} package from @uref{http://curl.haxx.se/}, or else -the @code{libwww} package from @uref{http://www.w3.org/Library/} or from +the @code{libwww} package from @uref{http://www.w3.org/Library/} or @uref{http://@-www.physio@-net.org/physio@-tools/libwww/}. One or both of these packages is provided with most current versions of GNU/Linux. (If you have a program called @code{curl-config}, then @code{libcurl} is installed @@ -7848,9 +8063,9 @@ @item libcurl or libwww (from Fink, @uref{http://fink.sourceforge.net/}) @item -an X11 package (from Fink, @uref{http://fink.sourceforge.net/}; XDarwin, -@uref{http://www.xdarwin.org/}; or Apple, -@uref{http://www.apple.com/macosx/features/x11/download/}) +an X11 package (from Fink, @uref{http://fink.sourceforge.net/}; Apple, +@uref{http://www.apple.com/macosx/features/@-x11/@-download/}; or XDarwin, +@uref{http://www.xdarwin.org/}) @item XView (from PhysioNet, @uref{http://www.physionet.org/physiotools/xview/}) @end itemize @@ -8551,19 +8766,24 @@ CinC is the major scientific meeting at which current research in ECG signal processing and modelling is discussed; the proceedings of the conference are probably the single best source of information in print about these topics. -CinC conferences have taken place annually since 1974, usually in September; in -even-numbered years, they are usually convened in North America, and in Europe -in odd-numbered years. The deadline for submission of abstracts is 1 May each -year. Proceedings of the conferences are published by the IEEE, and usually -appear about 3 months after the date of the conference. CinC will be in Lyon -in 2005 and (in a departure from the usual tradition) in Valencia in 2006. +CinC conferences have taken place annually since 1974, usually in September. +They are usually convened in North America and in Europe in alternate years. +The deadline for submission of abstracts is on or about 1 May each year. +Proceedings of the conferences are published by the IEEE, and usually +appear about 3 months after the date of the conference. CinC will be in +in Valencia (Spain) in 2006, and in Durham, NC (USA) in 2007. + +Since 2000, Computers in Cardiology and PhysioNet have jointly sponsored +an annual series of open challenges that invite participants to address +topics of interest to researchers and clinicians, often involving the +study of WFDB-compatible data sets made available via PhysioNet, and +culminating with research presentations and awards at CinC. See +@uref{http://physionet.org/challenge/} for further information. @item Proceedings of Computers in Cardiology (ISSN 0276-6574) @sp 1 -The Web of Science (@uref{http://isi1.isiknowledge.com/portal.cgi?DestApp=WOS}) -includes abstracts published in the Proceedings of CinC since 1996. IEEE -members can also find complete CinC proceedings from 1988 to the +IEEE members can find complete CinC proceedings from 1988 to the present using IEEEXplore (@uref{http://ieeexplore.ieee.org/}). Many universities provide access to these services for their students, faculty, and staff. Printed volumes of CinC proceedings are available from: @@ -8955,7 +9175,7 @@ George B. Moody -Copyright (C) 1989 -- 2003 George B. Moody +Copyright (C) 1989 -- 2006 George B. Moody Permission is granted to make and distribute verbatim copies of this guide provided that the copyright notice and this permission notice are diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/doc/wpg-src/wpg.ht0 wfdb-10.4.0/doc/wpg-src/wpg.ht0 --- wfdb-10.3.17/doc/wpg-src/wpg.ht0 2005-06-12 01:22:13.000000000 -0400 +++ wfdb-10.4.0/doc/wpg-src/wpg.ht0 2006-02-27 11:13:09.000000000 -0500 @@ -19,7 +19,7 @@ George B. Moody<BR> Harvard-MIT Division of Health Sciences and Technology<BR></STRONG></P><P> <P> -Copyright ©1980-2005 George B. Moody. +Copyright ©1980-2006 George B. Moody. <P> The most recent versions of the software described in this guide are freely downloadable from <A HREF="http://www.physionet.org/">PhysioNet</A>. For diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/doc/wug-src/Makefile.tpl wfdb-10.4.0/doc/wug-src/Makefile.tpl --- wfdb-10.3.17/doc/wug-src/Makefile.tpl 2002-07-18 20:54:19.000000000 -0400 +++ wfdb-10.4.0/doc/wug-src/Makefile.tpl 2006-02-27 12:47:40.000000000 -0500 @@ -1,5 +1,5 @@ -# file: Makefile.tpl G. Moody 24 May 2000 -# Last revised: 18 July 2002 +# file: Makefile.tpl G. Moody 24 May 2000 +# Last revised: 27 February 2006 # Change the settings below as appropriate for your setup. # Set COLORS to 'color' if you have a color printer and would like to print @@ -79,7 +79,7 @@ cd ../wug; rm -f .ID_MAP .IMG_PARAMS .ORIG_MAP images.* mv ../wug/*.pl . wave/scripts/fixwug.sh ../wug - cd ../wug; ln -s wug.htm index.html; find `pwd` -print | doschk + cd ../wug; ln -s wug.htm index.html wave/scripts/fixinfo >../../wave/wave.info touch wug.html diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/doc/wug-src/wave/scripts/dossify-html wfdb-10.4.0/doc/wug-src/wave/scripts/dossify-html --- wfdb-10.3.17/doc/wug-src/wave/scripts/dossify-html 2001-12-11 23:50:09.000000000 -0500 +++ wfdb-10.4.0/doc/wug-src/wave/scripts/dossify-html 2006-02-27 12:44:43.000000000 -0500 @@ -8,5 +8,7 @@ sed -f fixlinks <$F.html >$G.htm echo " done" done -sed 's/FFFFFF/FFD0B0/' <wug.htm >foo +sed 's/FFFFFF/FFD0B0/' <wug.htm | +sed 's/LEFT"><SMALL>/CENTER">/' | +sed 's/<\/SMALL>//' >foo mv foo wug.htm diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/doc/wug-src/wave/scripts/fixlinks wfdb-10.4.0/doc/wug-src/wave/scripts/fixlinks --- wfdb-10.3.17/doc/wug-src/wave/scripts/fixlinks 1999-06-24 11:38:45.000000000 -0400 +++ wfdb-10.4.0/doc/wug-src/wave/scripts/fixlinks 2006-02-27 12:06:13.000000000 -0500 @@ -1,4 +1,3 @@ s/\.html/\.htm/g -s/mit.edu\/order-form.htm/mit.edu\/order-form.html/g s/\.\(.\)\.htm/-\1.htm/g s/<BODY /<BODY bgcolor="FFFFFF" / diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/doc/wug-src/wug0.tex wfdb-10.4.0/doc/wug-src/wug0.tex --- wfdb-10.3.17/doc/wug-src/wug0.tex 2005-06-13 02:31:30.000000000 -0400 +++ wfdb-10.4.0/doc/wug-src/wug0.tex 2006-02-27 11:21:57.000000000 -0500 @@ -57,7 +57,7 @@ \pagestyle{empty} \vspace*{\fill} \noindent -Copyright \copyright 1992 -- 2005 George B. Moody +Copyright \copyright 1992 -- 2006 George B. Moody \vspace{1 in} \noindent @@ -986,8 +986,8 @@ \index{printing!signal window contents}\index{screen dump} \index{PostScript} -\index{SPARCprinter} -If a PostScript printer is available, try printing the contents of the +If a PostScript printer (or a PostScript interpreter such as GhostScript) +is available, try printing the contents of the signal window. To do this, press and hold the right mouse button while the pointer is above \menubutton{File}; then drag the pointer downwards until the {\sf Print} selection is @@ -4694,27 +4694,25 @@ \index{resolution!of display} \index{X Window System!XFree86 server} \item [A computer capable of acting as a \WAVE{} host] -(one for which a binary version of \WAVE{} is available). Virtually -any PC with a 386 or better CPU can run Linux, and such systems are -likely to be the least expensive choice. Ideally, a Linux PC to be -used as a \WAVE{} host should have at least 8 Mb of RAM, at least 200 -Mb of available disk space, a three-button mouse (or trackball), and a -graphics card and monitor (17-inch or larger, with a dot pitch of .26 -mm or less) capable of non-interlaced display at 65 Hz or faster with -a resolution of at least 1024x768 with 256 colors. In most cases, you -will also want the system to be equipped with a CD-ROM drive (for -loading software and digitized signals) and an Internet connection -(for obtaining data from PhysioNet and compatible sources). -Most PCs manufactured since 1995 will easily meet -these requirements; new PCs will exceed most of them by large factors. -In mid-2002, it was possible to assemble a suitable Linux PC for about -US\$300 (not including the monitor). It is not unreasonable to budget -an equal or greater amount for a good monitor, since \WAVE{}'s -usability depends to a significant extent on being able to see its -output clearly. If your budget permits, a flat-panel (LCD) monitor is -an excellent choice, particularly if you plan to do much annotation -editing, because these monitors typically present very stable images -that do not tire the eye. +Virtually any PC with a 386 or better CPU can run Linux, and such systems are +likely to be the least expensive choice. Ideally, a Linux PC to be used as a +\WAVE{} host should have at least 8 Mb of RAM, at least 200 Mb of available +disk space, a three-button mouse (or trackball), and a graphics card and +monitor (17-inch or larger, with a dot pitch of .26 mm or less) capable of +non-interlaced display at 65 Hz or faster with a resolution of at least +1024x768 with 256 colors. In most cases, you will also want the system to be +equipped with an Internet connection (for obtaining data and software from +PhysioNet and other sources).. Most PCs manufactured since 1995 will easily +meet these requirements; new PCs will exceed most of them by large factors. In +mid-2005, it was possible to assemble a suitable Linux PC for about US\$200 +(not including the monitor). It is not unreasonable to budget an equal or +greater amount for a good monitor, since \WAVE{}'s usability depends to a +significant extent on being able to see its output clearly. If your budget +permits, a flat-panel (LCD) monitor is an excellent choice, particularly if you +plan to do much annotation editing, because these monitors typically present +very stable images that do not tire the eye. Fully configured and supported +Linux PCs are available from many sources if you prefer not to assemble your +own; try a Google search for ``linux pc'' to find vendors. Inexpensive three-button mice, trackballs, and touchpads manufactured by Logitech and many others are widely available for PCs, and are @@ -4736,53 +4734,20 @@ require large amounts of RAM, it can use additional RAM very effectively, and you are likely to find that purchasing (say) 16 or 32 Mb of additional RAM results in a bigger performance improvement than spending the same amount on a -faster CPU. Fully configured and supported Linux PCs are available from many -vendors if you prefer not to assemble your own; see the Linux Commercial-HOWTO -for further information. +faster CPU. Although \WAVE{} now runs on MS-Windows, we still recommend using GNU/Linux as the platform of choice because of its greater speed, capability, configurability, security, and stability, and because of the wider -range of related software available for GNU/Linux. - -Macintoshes and SPARC-based systems may also be worth considering, although -they tend to be substantiallyly more expensive than comparable or -faster Linux PCs. - -\item [A source of digitized signals] -\index{SPARCstation}\index{PC}\index{WFDB Software Package}\index{MS-DOS} -\index{CD-ROM}\index{ADC boards}\index{data acquisition} -Desktop SPARC systems are equipped with a single-channel -analog-to-digital converter that may be adequate for some applications -(newer versions have high-speed two-channel 16-bit ADCs). Several -vendors supply data acquisition subsystems for SPARC systems, which -may be useful if you require more speed, resolution, or inputs. -\index{resolution!of ADC} -PC-based hardware and software for digitizing signals is available at -significantly lower cost from many vendors. The WFDB Software Package -includes MS-DOS software for converting signals from analog to digital -form and back again, using ISA-bus ADC boards from Microstar -Laboratories (see -\hyperref{ADC boards} -{section~} -{, page~\pageref{sec:adc-boards}} -{sec:adc-boards}). -Large collections of digitized reference recordings of ECGs and -other signals are freely available from -\htmladdnormallink{PhysioNet}{http://www.physionet.org/}, -and may be purchased on -\htmladdnormallink{CD-ROMs from MIT}{http://ecg.mit.edu/} -and others; several -CD-ROMs are currently available for use in basic research in -physiologic signal processing as well as for evaluation of -instrumentation. Single CD-ROM drives are widely -available for prices ranging from US\$50 to \$300, depending on speed; -CD-ROM changers and jukeboxes are also available at higher prices. +range of related software available for GNU/Linux. Other \WAVE{} users have +reported success on PCs running FreeBSD. Macintoshes running OS X +and SPARC-based systems may also be worth considering, although they tend to +be substantially more expensive than comparable or faster Linux or FreeBSD PCs. \end{description} \section{Printers} -\index{printing}\index{PostScript}\index{SPARCprinter}\index{Ghostscript} +\index{printing}\index{PostScript}\index{Ghostscript} All currently available \WAVE{}-compatible applications for printing require the use of a PostScript (or compatible) printer accessible to the \WAVE{} host @@ -4791,9 +4756,7 @@ paper output, therefore, you should obtain a PostScript printer, or a PostScript-compatible interpreter (such as the freely available GNU Ghostscript) for your printer, or you should be prepared to write your -own printing applications. For users of SBus-based SPARC systems, the -Sun SPARC\-printer is an excellent choice (less expensive and much -faster than standard PostScript printers, with better quality output). +own printing applications. \section{Remote access requirements} @@ -4826,97 +4789,10 @@ concern, an X terminal is probably a better choice than a networked PC. -\section{X11 window managers} -\index{window manager}\index{ICCCM} -Unlike other windowing systems, X does not impose a particular `look and feel' -on the user; rather, the user may select one of a number of `window managers' -that provide different user interfaces for common operations such as moving and -resizing windows. Window managers are X client applications that have a -special status allowing them to manipulate the windows of other X clients. Any -window manager that conforms to the ICCCM (a standard published by the X -Consortium) may be used with \WAVE{}; among these are {\tt fvwm}, -\index{olwm@{\tt olwm} (Open Look Window Manager)} -\index{olvwm@{\tt olvwm} (Open Look Virtual Window Manager)} -{\tt olwm}, and {\tt olvwm}, -included in source form with most Linux distributions -and widely available elsewhere ({\tt olwm} is also standard on Sun -workstations); and {\tt mwm} (the Motif window manager, included with most -current commercial UNIX systems). The Open Look window managers ({\tt olwm} -and {\tt olvwm}) are particularly recommended, since the others do not support -certain Open Look features of \WAVE{} (notably spot help and `pinnable' -popups). If you -\index{X terminal} -are using an MS-DOS PC or an X terminal to access \WAVE{}, the window -manager must usually be run remotely, often on the same computer that runs -\WAVE{}. (Note: these recommendations are several years old. Many -newer X11 window managers have appeared since then; \WAVE{} works -with any of them, although {\tt olwm} and {\tt olvwm} still have a -slight advantage over the others. - -\section{Data acquisition and digitization} -\label{sec:adc-boards} -\index{Linux}\index{digitizing signals}\index{ADC boards} -\index{sample command@{\tt sample} command (for digitization under MS-DOS)} -PC-based data acquisition is a good choice given the large number of ADC boards -available; note, however, that Linux drivers for these boards are rare. -The WFDB Software Package available separately from MIT includes an MS-DOS -program (named {\tt sample}) for digitization and replay of analog signals -using a DAP 1200- or 2400-series data acquisition board (available from -Microstar Laboratories, -\htmladdnormallink{http://www.mstarlabs.com/).}{http://www.mstarlabs.com/} - -Note that the \WAVE{} host -\index{WAVE host@\WAVE{} host} -must be able -to read the signal files. If you use an MS-DOS data acquisition -program, this can be accomplished in several ways: - -\begin{itemize} - -\item -The data acquisition PC can be set up to boot either Linux -\index{Linux} -or MS-DOS, -\index{MS-DOS} -and when running \WAVE{} under Linux, signal -files written to MS-DOS file systems can be read directly. (Current -versions of Linux can also read files in Windows NT, Windows 95, and -OS/2 file systems.) - -\item -Alternatively, you can transfer the digitized -signals to another system acting as the \WAVE{} host, either during -digitization (by writing to a network drive) or afterwards. Since -signal files are usually very large, Ethernet -\index{Ethernet} -transmission is -recommended. If -\index{sample command@{\tt sample} command (for digitization under MS-DOS)} -you use {\tt sample} for digitization, signal files can be written -directly on the host system's drive at rates up to 80,000 samples per -second using NFS (or up to 100,000 samples per second on local -disks). This configuration allows you to examine the signal files -using \WAVE{} as the data are being acquired; although \WAVE{} does -not currently support real-time, continuously updated display of -incoming data, it is not difficult to create a log file for \WAVE{} -that can be used to drive a continuously updated time-delayed display -(see -\hyperref{a note about automatic scrolling} -{section~} -{, page~\pageref{sec:autoscroll} } -{sec:autoscroll} -for details). - -\item -You can write digitized data to removable storage, then read the data on the -\WAVE{} host. Many devices are suitable for this purpose; consider -using writable CDs or DVDs, USB or Firewire disk drives, or compact -flash memory cards. -\end{itemize} - -\index{CD-ROM}\index{MIT-BIH Arrhythmia Database} \index{European ST-T +\section{Data} +\index{MIT-BIH Arrhythmia Database} \index{European ST-T Database}\index{MIT-BIH Polysomnographic Database} \index{MGH/MF -Waveform Database} You may also find that an existing database of +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/}, offers free on-line access to over 30 such databases with thousands of @@ -4934,44 +4810,31 @@ of signal databases). \section{About Linux} - \label{sec:linux} \index{Linux} As mentioned earlier, an excellent choice for a \WAVE{} host is a PC running Linux. Linux is a (very) complete, and completely free, robust, modern reimplementation of the UNIX operating system, written by Linus Torvalds and a cast of thousands. It is -available in source and ready-to-run form by anonymous FTP from many -sources, including -\htmladdnormallink{{\tt ftp://ftp.tux.org}}{ftp://ftp.tux.org}, -\htmladdnormallink{{\tt public.planetmirror.com}}{ftp://public.planetmirror.com/pub/linux}, and -\htmladdnormallink{{\tt ftp.funet.fi}}{ftp://ftp.funet.fi/pub/Linux}. +freely available in source and ready-to-run form from many +sources (LWN.net maintains a list of over 400 sites at +\htmladdnormallink{http://lwn.net/Distributions/}{http://lwn.net/Distributions/}). You can also obtain Linux on CD-ROMs from many commercial sources, generally at very low prices (typically US\$10 to \$40, depending mainly on the amount of printed documentation and technical support offered). Current Linux distributions include TCP/IP networking including NFS support, the complete collection of GNU software including the GNU -C/C++ compiler, Ghostscript, \TeX, and much more. Some also include +C/C++ compiler, Ghostscript, \TeX, X11R6, and much more. Some also include \index{XView}\index{olwm@{\tt olwm} (Open Look Window Manager)} \index{olvwm@{\tt olvwm} (Open Look Virtual Window Manager)} -X11R6, XView 3.2, {\tt olwm} and {\tt olvwm}; these are also available -from the sites above as well as from PhysioNet. For further +XView 3.2, {\tt olwm} and {\tt olvwm}; these are also available +from PhysioNet. For further information, visit the home page of the Linux Documentation Project (\htmladdnormallink{{\tt http://www.tldp.org/}} {http://www.tldp.org/}), where you may also find the Linux HOWTO documents mentioned earlier. -\index{format!of binary executable files} -Since mid-1995, Linux has supported ELF binaries, and current versions -of \WAVE{} for Linux are made available in this format. Older -versions of Linux used the {\tt a.out} binary format. If you have -been running one of these older versions of Linux, updating your system -to one with ELF support is highly recommended. Otherwise, you can attempt -to compile an {\tt a.out}-format WAVE from the -\htmladdnormallink{sources}{http://www.physionet.org/physiotools/wfdb/wave/} -available from PhysioNet. - \section{Other useful software} \label{sec:other-software} diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/examples/example7.c wfdb-10.4.0/examples/example7.c --- wfdb-10.3.17/examples/example7.c 2002-11-23 22:46:20.000000000 -0500 +++ wfdb-10.4.0/examples/example7.c 2005-10-19 17:09:48.000000000 -0400 @@ -7,7 +7,7 @@ { double *c, one = 1.0, vv, atof(); int i, j, nc = argc - 4, nsig; - long nsamp, t; + WFDB_Time nsamp, t, t0, t1; static WFDB_Sample *v; static WFDB_Siginfo *s; @@ -32,26 +32,32 @@ v = (WFDB_Sample *)malloc(nsig * sizeof(WFDB_Sample)); if (s == NULL || v == NULL) { fprintf(stderr, "insufficient memory\n"); - exit(3); + exit(4); } if (isigopen(argv[1], s, nsig) != nsig) - exit(3); - if (isigsettime(strtim(argv[2])) < 0) - exit(4); + exit(5); + t0 = strtim(argv[2]); + if (t0 < (WFDB_Time)0) t0 = -t0; + (void)sample(0, t0); + if (!sample_valid()) { + fprintf(stderr, "%s: inappropriate value for start time\n", + argv[0]); + exit(6); + } if ((nsamp = strtim(argv[3])) < 1) { fprintf(stderr, "%s: inappropriate value for duration\n", argv[0]); - exit(5); + exit(7); } + t1 = t0 + nsamp; if (osigopen("16l", s, nsig) != nsig) - exit(6); + exit(8); - (void)sample(0, 0L); - for (t = 0; t < nsamp && sample_valid(); t++) { + for (t = t0; t < t1 && sample_valid(); t++) { for (j = 0; j < nsig; j++) { for (i = 0, vv = 0.; i < nc; i++) if (c[i] != 0.) vv += c[i]*sample(j, t+i); - v[j] = (int)vv; + v[j] = (WFDB_Sample)vv; } if (putvec(v) < 0) break; } diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/fortran/example.f wfdb-10.4.0/fortran/example.f --- wfdb-10.3.17/fortran/example.f 2001-10-08 22:42:36.000000000 -0400 +++ wfdb-10.4.0/fortran/example.f 2006-02-23 23:35:58.000000000 -0500 @@ -1,9 +1,9 @@ C file: example.f G. Moody 23 August 1995 -C Last revised: 8 October 2001 (comments only) +C Last revised: 23 February 2006 C C ----------------------------------------------------------------------------- C Sample program illustrating use of Fortran wrappers for the WFDB library -C Copyright (C) 2001 George B. Moody +C Copyright (C) 1995-2006 George B. Moody C C This program is free software; you can redistribute it and/or modify it under C the terms of the GNU General Public License as published by the Free Software @@ -48,14 +48,16 @@ real f C Open up to 32 signals from record 100s. (There are only 2 signals in this -C record, however.) - i = isigopen("100s", 32) +C record, however.) Note how we force the string argument to end with an +C explicit NULL (CHAR(0)); this is necessary for any strings passed to C +C functions. + i = isigopen("100s"//CHAR(0), 32) write (6,1) i 1 format("Number of signals in record 100s = ", i2) C Check out the sampling frequency of record 100s. The returned value is C the sampling frequency in Hz, represented as a C double (Fortran real) value. - f = sampfreq("100s") + f = sampfreq("100s"//CHAR(0)) write (6,2) f 2 format("Sampling frequency = ", f6.2) diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/fortran/fsamples.f wfdb-10.4.0/fortran/fsamples.f --- wfdb-10.3.17/fortran/fsamples.f 2001-11-01 23:12:46.000000000 -0500 +++ wfdb-10.4.0/fortran/fsamples.f 2006-02-24 01:11:25.000000000 -0500 @@ -1,6 +1,6 @@ integer i, v(2), g - i = isigopen("100s", 2) + i = isigopen("100s"//CHAR(0), 2) do i = 1, 10 g = getvec(v) write (6,3) v(1), v(2) diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/fortran/Makefile.top wfdb-10.4.0/fortran/Makefile.top --- wfdb-10.3.17/fortran/Makefile.top 2003-05-06 16:37:21.000000000 -0400 +++ wfdb-10.4.0/fortran/Makefile.top 2006-02-24 01:19:25.000000000 -0500 @@ -1,19 +1,19 @@ # file: Makefile G. Moody 23 August 1995 -# Last revised: 8 October 2001 +# Last revised: 24 February 2006 # -# ----------------------------------------------------------------------------- +# ---------------------------------------------------------------------------- # UNIX 'make' description file for compiling the Fortran example program -# Copyright (C) 2001 George B. Moody +# Copyright (C) 1995-2006 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 -# Foundation; either version 2 of the License, or (at your option) any later -# version. +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) +# any later version. # # This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -# details. +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. # # You should have received a copy of the GNU General Public License along with # this program; if not, write to the Free Software Foundation, Inc., 59 Temple @@ -22,7 +22,7 @@ # You may contact the author by e-mail (george@mit.edu) or postal mail # (MIT Room E25-505A, Cambridge, MA 02139 USA). For updates to this software, # please visit PhysioNet (http://www.physionet.org/). -# _____________________________________________________________________________ +# ____________________________________________________________________________ # This file is used with the UNIX `make' command to compile the example # program in this directory. Since this program is intended for instruction diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/fortran/Makefile.tpl wfdb-10.4.0/fortran/Makefile.tpl --- wfdb-10.3.17/fortran/Makefile.tpl 2003-05-06 16:38:35.000000000 -0400 +++ wfdb-10.4.0/fortran/Makefile.tpl 2006-02-24 23:09:28.000000000 -0500 @@ -1,11 +1,25 @@ - +# This example works with either f77 (g77) or gfortran. example: example.f wfdbf.c - f77 -o example -fwritable-strings example.f wfdbf.c -lwfdb + $(F77) -o example -DFIXSTRINGS example.f wfdbf.c -lwfdb + +wfdbf.o: wfdbf.c + $(CC) -g -O -DFIXSTRINGS wfdbf.c + # If you have `f2c', but not `f77', use `make example-alt' instead of `make'. example-alt: example.f wfdbf.c f2c example.f $(CC) -o example example.c wfdbf.c -lf2c -lm -lwfdb + +# 'make install' copies the wrapper sources into the directory where the +# WFDB headers are also installed. +install: + ../install.sh $(INCDIR)/wfdb wfdbf.c + $(SETPERMISSIONS) $(INCDIR)/wfdb/wfdbf.c + +uninstall: + ../uninstall.sh $(INCDIR)/wfdb wfdbf.c + clean: rm -f example example.c *.o *~ diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/fortran/README wfdb-10.4.0/fortran/README --- wfdb-10.3.17/fortran/README 2001-10-09 00:13:59.000000000 -0400 +++ wfdb-10.4.0/fortran/README 2006-02-24 01:23:24.000000000 -0500 @@ -1,8 +1,8 @@ file: README G. Moody 28 July 1995 - Last revised: 8 October 2001 -_______________________________________________________________________________ + Last revised: 24 February 2006 +______________________________________________________________________________ Fortran wrappers for the WFDB library -Copyright (C) 2001 George B. Moody +Copyright (C) 1995-2006 George B. Moody These wrappers are free software; you can redistribute them and/or modify them under the terms of the GNU Library General Public License as published by the @@ -14,27 +14,29 @@ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. -You should have received a copy of the GNU Library General Public License along -with these wrappers; if not, write to the Free Software Foundation, Inc., 59 -Temple Place - Suite 330, Boston, MA 02111-1307, USA. +You should have received a copy of the GNU Library General Public License +along with these wrappers; if not, write to the Free Software Foundation, +Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. You may contact the author by e-mail (george@mit.edu) or postal mail (MIT Room E25-505A, Cambridge, MA 02139 USA). For updates to this software, please visit PhysioNet (http://www.physionet.org/). -_______________________________________________________________________________ +______________________________________________________________________________ -A set of `wrapper functions' is provided in this directory for those who wish +A set of 'wrapper functions' is provided in this directory for those who wish to use the WFDB library together with applications written in Fortran. In order to use them, you will still need a C or C++ compiler to compile the WFDB library and the wrapper functions themselves; in addition, if you are cross-compiling, you will need a version of the standard C library for your target system. If you do not have a C compiler or the standard C library, the freely available GNU C/C++ compiler and the GNU C library are highly -recommended (see SOURCES, in the parent of this directory, for further -information); these can be used with several commercial Fortran compilers, or -with either `f2c' (a Fortran-to- C translator) or `g77' (the GNU Fortran -compiler). `f2c' and `g77' are also freely available from the same sources as -the GNU C/C++ compiler. +recommended; these can be used with several commercial Fortran compilers, or +with either 'f2c' (a Fortran-to-C translator) or 'g77' (the original GNU +Fortran compiler). The (currently) experimental GNU Fortran 9x compiler, +'gfortran', is able to compile the wrappers and some simple programs but is +not sufficiently complete to be useful for larger programs, though this should +change as 'gfortran' matures. 'f2c', 'g77', and 'gfortran' are all freely +available from the same sources as the GNU C/C++ compiler. In most cases, the WFDB library functions cannot be called directly from Fortran programs, for one or more of the following reasons: @@ -57,14 +59,14 @@ README this file wfdbf.c the wrappers (written in C for use with Fortran programs) example.f a sample Fortran program that illustrates use of the wrappers -Makefile UNIX `make' description file for compiling the sample program +Makefile UNIX 'make' description file for compiling the sample program General notes on using the wrapper functions -------------------------------------------- -Wrappers are provided in `wfdbf.c' for all of the WFDB library functions except -setmsheader. See the sample program (`example.f', in this directory) -to see how the wrappers are used, and see `Makefile' to see how to compile +Wrappers are provided in 'wfdbf.c' for all of the WFDB library functions except +setmsheader. See the sample program ('example.f', in this directory) +to see how the wrappers are used, and see 'Makefile' to see how to compile and link a Fortran program with the wrappers and the WFDB library. Include the statements @@ -73,7 +75,7 @@ (or the equivalent for your dialect of Fortran) in your Fortran program to ensure that these functions (except for the four listed in the second statement) will be understood to return integer*4 values (equivalent to C -`long' values). +'long' values). Note that Fortran arrays are 1-based, and C arrays are 0-based. Signal and annotator numbers passed to these functions must be 0-based. Thus, for @@ -90,20 +92,20 @@ If this discussion is not clear, refer to the WFDB Programmer's Guide, especially to the Glossary entries for Annotator number and Signal number. -Certain parameters are defined in `wfdb.h' (in the `lib' directory at the same +Certain parameters are defined in 'wfdb.h' (in the 'lib' directory at the same level as this one; a copy of this file is referenced by the C statement #include <wfdb/wfdb.h> -near the top of most of the *.c files in the `app' directory). +near the top of most of the *.c files in the 'app' directory). If you are using a UNIX Fortran compiler, or a Fortran-to-C translator, note -that the trailing `_' in the names of the functions defined in wfdbf.c should -*not* appear in your Fortran program; thus, for example, `annopen1_' should be -invoked as `annopen1'. UNIX Fortran compilers and translators append a `_' to +that the trailing '_' in the names of the functions defined in wfdbf.c should +*not* appear in your Fortran program; thus, for example, 'annopen1_' should be +invoked as 'annopen1'. UNIX Fortran compilers and translators append a '_' to the names of all external symbols referenced in Fortran source files when generating object files. Thus the linker can recognize that annopen1_ (defined in wfdbf.c) is the function required by a Fortran program that invokes -`annopen1'; if the Fortran program were to invoke `annopen1_', the linker would -search (unsuccessfully) for a function named `annopen1__'. +'annopen1'; if the Fortran program were to invoke 'annopen1_', the linker would +search (unsuccessfully) for a function named 'annopen1__'. If you are using a Fortran compiler that does not follow this convention, you are on your own. @@ -144,18 +146,39 @@ really need this function in a Fortran program, write a Fortran version of it using the C version as a model; this is left as an exercise for the reader. -Note to users of g77 (the GNU Fortran compiler) ------------------------------------------------ +Note to users of gfortran (the experimental GNU Fortran compiler) +----------------------------------------------------------------- -When compiling the wrappers, use the option -fwritable-strings, as in: - g77 -c -DFIXSTRINGS -fwritable-strings wfdbf.c +As of February 2006, I have not been successful in compiling anything other +than trivial programs with gfortran, which (according to its documentation) is +a work in progress. This situation will change (I hope), but if you encounter +problems with gfortran I recommend g77. + +Note to users of f77 or g77 (the original GNU Fortran compiler) +--------------------------------------------------------------- + +The original UNIX Fortran 77 compiler was called f77. The GNU Fortran 77 +compiler is compatible with the original f77, and it is frequently installed +under both names on modern platforms. + +To install g77 on Fedora Core 4 (which provides only gfortran by default), make +sure that yum is working and (as root) do this: + yum install compat-gcc-32-g77 + +When compiling the wrappers, use the option -DFIXSTRINGS, as in: + g77 -c -DFIXSTRINGS wfdbf.c +and then link wfdbf.o and the WFDB library to your Fortran code by: + g77 -o myprogram myprogram.f wfdbf.o -lwfdb + +If you prefer, you can compile the wrappers at the same time as your Fortran +code. For example: + g77 -o myprogram myprogram.f -DFIXSTRINGS wfdbf.c -lwfdb -You should also be sure to use -fwritable-strings when compiling your -Fortran code. For example: - g77 -o myprogram -fwritable-strings myprogram.f wfdbf.o -lwfdb +If you use the older 'f2c' (Fortran-to-C translator), do not use -DFIXSTRINGS +when compiling wfdbf.c. -If you use the older 'f2c' (Fortran-to-C translator), it is not necessary to -use -fwritable-strings. +It is no longer necessary to use the deprecated '-fwritable-strings' option +when compiling the wrappers. If you compile and run the example program, its output should be: diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/fortran/wfdbf.c wfdb-10.4.0/fortran/wfdbf.c --- wfdb-10.3.17/fortran/wfdbf.c 2002-05-23 11:23:49.000000000 -0400 +++ wfdb-10.4.0/fortran/wfdbf.c 2006-02-24 23:23:38.000000000 -0500 @@ -1,9 +1,9 @@ -/* file: wfdbf.c G. Moody 23 August 1995 - Last revised: 23 May 2002 +/* file: wfdbf.c G. Moody 23 August 1995 + Last revised: 24 February 2006 wfdblib 10.4.0 _______________________________________________________________________________ wfdbf: Fortran wrappers for the WFDB library functions -Copyright (C) 2002 George B. Moody +Copyright (C) 1995-2006 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 @@ -75,24 +75,33 @@ /* #define FIXSTRINGS */ #ifdef FIXSTRINGS -fcstring(s) /* change final space to null */ -char *s; +/* This function leaks memory! Ideally we would like to free(t) once *t is + no longer needed. If this is a concern, we might push all values assigned + to t onto a stack and free them all on exit. In practice we are usually + dealing with a small number of short strings. */ +char *fcstring(char *s) /* change final space to null */ { + char *p = s, *t; + while (*s && *s != ' ') s++; - *s = '\0'; + t = calloc(1, s-p+1); + if (s > p) strncpy(t, p, s-p); + return (t); } -cfstring(s) /* change final null to space */ -char *s; +char *cfstring(char *s) /* change final null to space */ { + char *p = s; + while (*s) s++; *s = ' '; + return (p); } #else -#define fcstring(s) -#define cfstring(s) +#define fcstring(s) (s) +#define cfstring(s) (s) #endif /* Static data shared by the wrapper functions. Since Fortran does not support @@ -112,14 +121,10 @@ needed in the C library. */ -long setanninfo_(a, name, stat) -long *a; -char *name; -long *stat; +long setanninfo_(long int *a, char *name, long int *stat) { if (0 <= *a && *a < WFDB_MAXANN*2) { - fcstring(name); - ainfo[*a].name = name; + ainfo[*a].name = fcstring(name); ainfo[*a].stat = *stat; return (0L); } @@ -127,13 +132,7 @@ return (-1L); } -long getsiginfo_(s, fname, desc, units, gain, initval, group, fmt, spf, - bsize, adcres, adczero, baseline, nsamp, cksum) -long *s; -char *fname, *desc, *units; -double *gain; -long *initval, *group, *fmt, *spf, *bsize, *adcres, *adczero, *baseline, - *nsamp, *cksum; +long getsiginfo_(long int *s, char *fname, char *desc, char *units, double *gain, long int *initval, long int *group, long int *fmt, long int *spf, long int *bsize, long int *adcres, long int *adczero, long int *baseline, long int *nsamp, long int *cksum) { if (0 <= *s && *s < WFDB_MAXSIG) { fname = sinfo[*s].fname; @@ -156,13 +155,7 @@ return (-1L); } -long setsiginfo_(s, fname, desc, units, gain, initval, group, fmt, spf, - bsize, adcres, adczero, baseline, nsamp, cksum) -long *s; -char *fname, *desc, *units; -double *gain; -long *initval, *group, *fmt, *spf, *bsize, *adcres, *adczero, *baseline, - *nsamp, *cksum; +long setsiginfo_(long int *s, char *fname, char *desc, char *units, double *gain, long int *initval, long int *group, long int *fmt, long int *spf, long int *bsize, long int *adcres, long int *adczero, long int *baseline, long int *nsamp, long int *cksum) { if (0 <= *s && *s < WFDB_MAXSIG) { sinfo[*s].fname = fname; @@ -187,78 +180,60 @@ /* Before using annopen_, set up the annotation information structures using setanninfo_. */ -long annopen_(record, nann) -char *record; -long *nann; +long annopen_(char *record, long int *nann) { - fcstring(record); - return (annopen(record, ainfo, (unsigned int)(*nann))); + return (annopen(fcstring(record), ainfo, (unsigned int)(*nann))); } /* After using isigopen_ or osigopen_, use getsiginfo_ to obtain the contents of the signal information structures if necessary. */ -long isigopen_(record, nsig) -char *record; -long *nsig; +long isigopen_(char *record, long int *nsig) { - fcstring(record); - return (isigopen(record, sinfo, (unsigned int)(*nsig))); + return (isigopen(fcstring(record), sinfo, (unsigned int)(*nsig))); } -long osigopen_(record, nsig) -char *record; -long *nsig; +long osigopen_(char *record, long int *nsig) { - fcstring(record); - return (osigopen(record, sinfo, (unsigned int)(*nsig))); + return (osigopen(fcstring(record), sinfo, (unsigned int)(*nsig))); } /* Before using osigfopen_, use setsiginfo_ to set the contents of the signal information structures. */ -long osigfopen_(nsig) -long *nsig; +long osigfopen_(long int *nsig) { return (osigfopen(sinfo, (unsigned int)(*nsig))); } /* Before using wfdbinit_, use setanninfo_ and setsiginfo_ to set the contents of the annotation and signal information structures. */ -long wfdbinit_(record, nann, nsig) -char *record; -long *nann, *nsig; +long wfdbinit_(char *record, long int *nann, long int *nsig) { - fcstring(record); - return (wfdbinit(record, ainfo, (unsigned int)(*nann), - sinfo, (unsigned int)(*nsig))); + return (wfdbinit(fcstring(record), ainfo, (unsigned int)(*nann), + sinfo, (unsigned int)(*nsig))); } -long setgvmode_(mode) -long *mode; +long setgvmode_(long int *mode) { setgvmode((int)(*mode)); return (0L); } -long getspf_(dummy) -long *dummy; +long getspf_(long int *dummy) { return (getspf()); } -long setifreq_(freq) -double *freq; +long setifreq_(double *freq) { return (setifreq(*freq)); } -double getifreq_(dummy) -long *dummy; +double getifreq_(long int *dummy) { return (getifreq()); } -long getvec_(long_vector) -long *long_vector; +long getvec_(long int *long_vector) { #ifndef REPACK return (getvec((WFDB_Sample *)long_vector)); @@ -273,8 +248,7 @@ #endif } -long getframe_(long_vector) -long *long_vector; +long getframe_(long int *long_vector) { #ifndef REPACK return (getframe((WFDB_Sample *)long_vector)); @@ -290,8 +264,7 @@ #endif } -long putvec_(long_vector) -long *long_vector; +long putvec_(long int *long_vector) { #ifndef REPACK return (putvec((WFDB_Sample *)long_vector)); @@ -305,9 +278,7 @@ #endif } -long getann_(annotator, time, anntyp, subtyp, chan, num, aux) -long *annotator, *time, *anntyp, *subtyp, *chan, *num; -char *aux; +long getann_(long int *annotator, long int *time, long int *anntyp, long int *subtyp, long int *chan, long int *num, char *aux) { static WFDB_Annotation iann; int i, j; @@ -324,9 +295,7 @@ return (i); } -long ungetann_(annotator, time, anntyp, subtyp, chan, num, aux) -long *annotator, *time, *anntyp, *subtyp, *chan, *num; -char *aux; +long ungetann_(long int *annotator, long int *time, long int *anntyp, long int *subtyp, long int *chan, long int *num, char *aux) { static WFDB_Annotation oann; int i, j; @@ -340,200 +309,171 @@ return (ungetann((WFDB_Annotator)(*annotator), &oann)); } -long putann_(annotator, time, anntyp, subtyp, chan, num, aux) -long *annotator, *time, *anntyp, *subtyp, *chan, *num; -char *aux; +long putann_(long int *annotator, long int *time, long int *anntyp, long int *subtyp, long int *chan, long int *num, char *aux) { static WFDB_Annotation oann; int i, j; + char *p, *q = NULL; oann.time = *time; oann.anntyp = *anntyp; oann.subtyp = *subtyp; oann.chan = *chan; oann.num = *num; - oann.aux = aux; - return (putann((WFDB_Annotator)(*annotator), &oann)); + if (aux) { + p = fcstring(aux); + q = calloc(strlen(p)+2, 1); + *q = strlen(p); + strcpy(q+1, p); + } + oann.aux = q; + i = putann((WFDB_Annotator)(*annotator), &oann); + if (q) free(q); + return (i); } -long isigsettime_(time) -long *time; +long isigsettime_(long int *time) { return (isigsettime((WFDB_Time)(*time))); } -long isgsettime_(group, time) -long *group, *time; +long isgsettime_(long int *group, long int *time) { return (isgsettime((WFDB_Group)(*group), (WFDB_Time)(*time))); } -long iannsettime_(time) -long *time; +long iannsettime_(long int *time) { return (iannsettime((WFDB_Time)(*time))); } -long ecgstr_(code, string) -long *code; -char *string; +long ecgstr_(long int *code, char *string) { strcpy(string, ecgstr((int)(*code))); cfstring(string); return (0L); } -long strecg_(string) -char *string; +long strecg_(char *string) { - fcstring(string); - return (strecg(string)); + return (strecg(fcstring(string))); } -long setecgstr_(code, string) -long *code; -char *string; +long setecgstr_(long int *code, char *string) { - fcstring(string); - return (setecgstr((int)(*code), string)); + return (setecgstr((int)(*code), fcstring(string))); } -long annstr_(code, string) -long *code; -char *string; +long annstr_(long int *code, char *string) { strcpy(string, annstr((int)(*code))); cfstring(string); return (0L); } -long strann_(string) -char *string; +long strann_(char *string) { - fcstring(string); - return (strann(string)); + return (strann(fcstring(string))); } -long setannstr_(code, string) -long *code; -char *string; +long setannstr_(long int *code, char *string) { - fcstring(string); - return (setannstr((int)(*code), string)); + return (setannstr((int)(*code), fcstring(string))); } -long anndesc_(code, string) -long *code; -char *string; +long anndesc_(long int *code, char *string) { strcpy(string, anndesc((int)(*code))); cfstring(string); return (0L); } -long setanndesc_(code, string) -long *code; -char *string; +long setanndesc_(long int *code, char *string) { - fcstring(string); - return (setanndesc((int)(*code), string)); + return (setanndesc((int)(*code), fcstring(string))); } -long iannclose_(annotator) -long *annotator; +long iannclose_(long int *annotator) { iannclose((WFDB_Annotator)(*annotator)); return (0L); } -long oannclose_(annotator) -long *annotator; +long oannclose_(long int *annotator) { oannclose((WFDB_Annotator)(*annotator)); return (0L); } -long timstr_(time, string) -long *time; -char *string; +long timstr_(long int *time, char *string) { strcpy(string, timstr((WFDB_Time)(*time))); cfstring(string); return (0L); } -long mstimstr_(time, string) -long *time; -char *string; +long mstimstr_(long int *time, char *string) { strcpy(string, mstimstr((WFDB_Time)(*time))); cfstring(string); return (0L); } -long strtim_(string) -char *string; +long strtim_(char *string) { - fcstring(string); - return (strtim(string)); + return (strtim(fcstring(string))); } -long datstr_(date, string) -long *date; -char *string; +long datstr_(long int *date, char *string) { strcpy(string, datstr((WFDB_Date)(*date))); cfstring(string); return (0L); } -long strdat_(string) -char *string; +long strdat_(char *string) { - fcstring(string); - return (strdat(string)); + return (strdat(fcstring(string))); } -long adumuv_(signal, ampl) -long *signal, *ampl; +long adumuv_(long int *signal, long int *ampl) { return (adumuv((WFDB_Signal)(*signal), (WFDB_Sample)(*ampl))); } -long muvadu_(signal, microvolts) -long *signal, *microvolts; +long muvadu_(long int *signal, long int *microvolts) { return (muvadu((WFDB_Signal)(*signal), (int)(*microvolts))); } -double aduphys_(signal, ampl) -long *signal, *ampl; +double aduphys_(long int *signal, long int *ampl) { return (aduphys((WFDB_Signal)(*signal), (WFDB_Sample)(*ampl))); } -long physadu_(signal, v) -long *signal; -double *v; +long physadu_(long int *signal, double *v) { return (physadu((WFDB_Signal)(*signal), *v)); } -long calopen_(calibration_filename) -char *calibration_filename; +long sample_(long int *signal, long int *t) +{ + return (sample((WFDB_Signal)(*signal), (WFDB_Time)(*t))); +} + +long sample_valid_(long int *dummy) { - fcstring(calibration_filename); - return (calopen(calibration_filename)); + return (sample_valid()); } -long getcal_(description, units, low, high, scale, caltype) -char *description, *units; -double *low, *high, *scale; -long *caltype; +long calopen_(char *calibration_filename) { - fcstring(description); - fcstring(units); - if (getcal(description, units, &cinfo) == 0) { + return (calopen(fcstring(calibration_filename))); +} + +long getcal_(char *description, char *units, double *low, double *high, double *scale, long int *caltype) +{ + if (getcal(fcstring(description), fcstring(units), &cinfo) == 0) { *low = cinfo.low; *high = cinfo.high; *scale = cinfo.scale; @@ -544,15 +484,10 @@ return (-1L); } -long putcal_(description, units, low, high, scale, caltype) -char *description, *units; -double *low, *high, *scale; -long *caltype; -{ - fcstring(description); - fcstring(units); - cinfo.sigtype = description; - cinfo.units = units; +long putcal_(char *description, char *units, double *low, double *high, double *scale, long int *caltype) +{ + cinfo.sigtype = fcstring(description); + cinfo.units = fcstring(units); cinfo.low = *low; cinfo.high = *high; cinfo.scale = *scale; @@ -560,196 +495,164 @@ return (putcal(&cinfo)); } -long newcal_(calibration_filename) -char *calibration_filename; +long newcal_(char *calibration_filename) { - fcstring(calibration_filename); - return (newcal(calibration_filename)); + return (newcal(fcstring(calibration_filename))); } -long flushcal_(dummy) -long *dummy; +long flushcal_(long int *dummy) { flushcal(); return (0L); } -long getinfo_(record, string) -char *record, *string; +long getinfo_(char *record, char *string) { - fcstring(record); - strcpy(string, getinfo(record)); + strcpy(string, getinfo(fcstring(record))); cfstring(string); return (0L); } -long putinfo_(string) -char *string; +long putinfo_(char *string) { - fcstring(string); - return (putinfo(string)); + return (putinfo(fcstring(string))); } -long newheader_(record) -char *record; +long newheader_(char *record) { - fcstring(record); - return (newheader(record)); + return (newheader(fcstring(record))); } /* Before using setheader_, use setsiginfo to set the contents of the signal information structures. */ -long setheader_(record, nsig) -char *record; -long *nsig; +long setheader_(char *record, long int *nsig) { - fcstring(record); - return (setheader(record, sinfo, (unsigned int)(*nsig))); + return (setheader(fcstring(record), sinfo, (unsigned int)(*nsig))); } /* No wrapper is provided for setmsheader. */ -long wfdbgetskew_(s) -long *s; +long wfdbgetskew_(long int *s) { return (wfdbgetskew((WFDB_Signal)(*s))); } -long wfdbsetskew_(s, skew) -long *s, *skew; +long wfdbsetiskew_(long int *s, long int *skew) +{ + wfdbsetiskew((WFDB_Signal)(*s), (int)(*skew)); + return (0L); +} + +long wfdbsetskew_(long int *s, long int *skew) { wfdbsetskew((WFDB_Signal)(*s), (int)(*skew)); return (0L); } -long wfdbgetstart_(s) -long *s; +long wfdbgetstart_(long int *s) { return (wfdbgetstart((WFDB_Signal)(*s))); } -long wfdbsetstart_(s, bytes) -long *s, *bytes; +long wfdbsetstart_(long int *s, long int *bytes) { wfdbsetstart((WFDB_Signal)(*s), *bytes); return (0L); } -long wfdbquit_(dummy) -long *dummy; +long wfdbquit_(long int *dummy) { wfdbquit(); return (0L); } -double sampfreq_(record) -char *record; +double sampfreq_(char *record) { - fcstring(record); - return (sampfreq(record)); + return (sampfreq(fcstring(record))); } -long setsampfreq_(frequency) -double *frequency; +long setsampfreq_(double *frequency) { return (setsampfreq((WFDB_Frequency)(*frequency))); } -double getcfreq_(dummy) -long *dummy; +double getcfreq_(long int *dummy) { return (getcfreq()); } -long setcfreq_(frequency) -double *frequency; +long setcfreq_(double *frequency) { setcfreq((WFDB_Frequency)(*frequency)); return (0L); } -double getbasecount_(dummy) -long *dummy; +double getbasecount_(long int *dummy) { return (getbasecount()); } -long setbasecount_(count) -double *count; +long setbasecount_(double *count) { setbasecount(*count); return (0L); } -long setbasetime_(string) -char *string; +long setbasetime_(char *string) { - fcstring(string); - return (setbasetime(string)); + return (setbasetime(fcstring(string))); } -long wfdbquiet_(dummy) -long *dummy; +long wfdbquiet_(long int *dummy) { wfdbquiet(); return (0L); } -long wfdbverbose_(dummy) -long *dummy; +long wfdbverbose_(long int *dummy) { wfdbverbose(); return (0L); } -long wfdberror_(string) -char *string; +long wfdberror_(char *string) { strcpy(string, wfdberror()); cfstring(string); return (0L); } -long setwfdb_(string) -char *string; +long setwfdb_(char *string) { - fcstring(string); - setwfdb(string); + setwfdb(fcstring(string)); return (0L); } -long getwfdb_(string) -char *string; +long getwfdb_(char *string) { strcpy(string, getwfdb()); cfstring(string); return (0L); } -long setibsize_(input_buffer_size) -long *input_buffer_size; +long setibsize_(long int *input_buffer_size) { return (setibsize((int)(*input_buffer_size))); } -long setobsize_(output_buffer_size) -long *output_buffer_size; +long setobsize_(long int *output_buffer_size) { return (setobsize((int)(*output_buffer_size))); } -long wfdbfile_(file_type, record, pathname) -char *file_type, *record, *pathname; +long wfdbfile_(char *file_type, char *record, char *pathname) { - fcstring(file_type); - fcstring(record); - strcpy(pathname, wfdbfile(file_type, record)); + strcpy(pathname, wfdbfile(fcstring(file_type), fcstring(record))); cfstring(pathname); return (0L); } -long wfdbflush_(dummy) -long *dummy; +long wfdbflush_(long int *dummy) { wfdbflush(); return (0L); @@ -758,71 +661,60 @@ /* The functions below can be used in place of the macros defined in <wfdb/ecgmap.h>. */ -long isann_(anntyp) -long *anntyp; +long isann_(long int *anntyp) { return ((long)(isann(*anntyp))); } -long isqrs_(anntyp) -long *anntyp; +long isqrs_(long int *anntyp) { return ((long)(isqrs(*anntyp))); } -long setisqrs_(anntyp, value) -long *anntyp, *value; +long setisqrs_(long int *anntyp, long int *value) { setisqrs(*anntyp, *value); return (0L); } -long map1_(anntyp) -long *anntyp; +long map1_(long int *anntyp) { return ((long)(map1(*anntyp))); } -long setmap1_(anntyp, value) -long *anntyp, *value; +long setmap1_(long int *anntyp, long int *value) { setmap1(*anntyp, *value); return (0L); } -long map2_(anntyp) -long *anntyp; +long map2_(long int *anntyp) { return ((long)(map1(*anntyp))); } -long setmap2_(anntyp, value) -long *anntyp, *value; +long setmap2_(long int *anntyp, long int *value) { setmap1(*anntyp, *value); return (0L); } -long ammap_(anntyp) -long *anntyp; +long ammap_(long int *anntyp) { return ((long)(ammap(*anntyp))); } -long mamap_(anntyp, subtyp) -long *anntyp, *subtyp; +long mamap_(long int *anntyp, long int *subtyp) { return ((long)(mamap(*anntyp, *subtyp))); } -long annpos_(anntyp) -long *anntyp; +long annpos_(long int *anntyp) { return ((long)(annpos(*anntyp))); } -long setannpos_(anntyp, value) -long *anntyp, *value; +long setannpos_(long int *anntyp, long int *value) { setannpos(*anntyp, *value); return (0L); diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/INSTALL wfdb-10.4.0/INSTALL --- wfdb-10.3.17/INSTALL 2005-06-08 14:56:59.000000000 -0400 +++ wfdb-10.4.0/INSTALL 2006-03-02 18:23:26.000000000 -0500 @@ -1,5 +1,5 @@ file: INSTALL G. Moody 30 January 2000 - Last revised: 8 June 2005 + Last revised: 2 March 2006 WFDB Software Package installation notes These notes are infrequently updated, but are included here for those who may @@ -63,10 +63,9 @@ All platforms: free from http://physionet.org/physiotools/xview/ -Detailed instructions for obtaining and installing these prerequisites, all -of which are free, open-source software, are included in the WFDB quick-start -guides for the popular platforms (see above). Brief notes about other -platforms are at the end of this file. +Detailed instructions for obtaining and installing these prerequisites are +included in the WFDB quick-start guides for the popular platforms (see above). +Brief notes about other platforms are at the end of this file. BUILDING AND INSTALLING @@ -106,20 +105,17 @@ make uninstall from this directory. You will need root permissions to uninstall unless you changed WFDBROOT before installing the package. - -This file contains separate sets of notes for GNU/Linux, Mac OS/X, -and MS-Windows, followed by brief notes on other ports. - _______________________________________________________________________________ -Under MacOS 9 and earlier, or other operating systems +Under MS-DOS, MacOS 9 and earlier, or other operating systems Sorry, but you are on your own here. Previous versions of the WFDB library -and some of the applications have been compiled successfully by Macintosh -users (and on VMS, among other environments). The sources are written in -highly portable C and should not be difficult to port to any environment where -an ANSI/ISO or K&R C compiler and the standard C library are available. +and some of the applications have been compiled successfully by MS-DOS and +Macintosh users (and on OS/2 and VMS, among other environments). The sources +are written in highly portable C and should not be difficult to port to any +environment where an ANSI/ISO or K&R C compiler and the standard C library are +available. Often vendors of proprietary compilers and operating systems provide little or no documentation about how to build libraries (especially shared/dynamically diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/lib/annot.c wfdb-10.4.0/lib/annot.c --- wfdb-10.3.17/lib/annot.c 2004-11-14 11:10:24.000000000 -0500 +++ wfdb-10.4.0/lib/annot.c 2006-02-23 17:45:38.000000000 -0500 @@ -1,10 +1,10 @@ /* file: annot.c G. Moody 13 April 1989 - Last revised: 14 November 2004 wfdblib 10.3.14 + Last revised: 23 February 2006 wfdblib 10.4.0 WFDB library functions for annotations _______________________________________________________________________________ wfdb: a library for reading and writing annotated waveforms (time series data) -Copyright (C) 1989-2004 George B. Moody +Copyright (C) 1989-2006 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 @@ -27,27 +27,41 @@ This file contains definitions of the following functions, which are not visible outside of this file: - get_ann_table (reads tables used by annstr, strann, and anndesc) - put_ann_table (writes tables used by annstr, strann, and anndesc) - allociann (sets max number of simultaneously open input annotators) - allocoann (sets max number of simultaneously open output annotators) + get_ann_table (reads tables used by annstr, strann, and anndesc) + put_ann_table (writes tables used by annstr, strann, and anndesc) + allociann (sets max # of simultaneously open input annotators) + allocoann (sets max # of simultaneously open output annotators) This file also contains definitions of the following WFDB library functions: - annopen (opens annotation files) - getann (reads an annotation) - ungetann [5.3] (pushes an annotation back into an input stream) - putann (writes an annotation) - iannsettime (skips to a specified time in input annotation files) - ecgstr (converts MIT annotation codes to ASCII strings) - strecg (converts ASCII strings to MIT annotation codes) - setecgstr (modifies code-to-string translation table) - annstr [5.3] (converts user-defined annotation codes to ASCII strings) - strann [5.3] (converts ASCII strings to user-defined annotation codes) - setannstr [5.3](modifies code-to-string translation table) - anndesc [5.3] (converts user-defined annotation codes to text descriptions) - setanndesc [5.3](modifies code-to-text translation table) - iannclose [9.1](closes an input annotation file) - oannclose [9.1](closes an output annotation file) + annopen (opens annotation files) + getann (reads an annotation) + ungetann [5.3] (pushes an annotation back into an input stream) + putann (writes an annotation) + iannsettime (skips to a specified time in input annotation files) + ecgstr (converts MIT annotation codes to ASCII strings) + strecg (converts ASCII strings to MIT annotation codes) + setecgstr (modifies code-to-string translation table) + annstr [5.3] (converts user-defined annot codes to ASCII strings) + strann [5.3] (converts ASCII strings to user-defined annot codes) + setannstr [5.3] (modifies code-to-string translation table) + anndesc [5.3] (converts user-defined annot codes to descriptions) + setanndesc [5.3] (modifies code-to-text translation table) + iannclose [9.1] (closes an input annotation file) + oannclose [9.1] (closes an output annotation file) + + These functions are intended primarily for the use by WFDB wrappers: + + wfdb_isann [10.4] (function version of isann, see ecgmap.h) + wfdb_isqrs [10.4] (function version of isqrs, see ecgmap.h) + wfdb_setisqrs [10.4] (function version of setisqrs, see ecgmap.h) + wfdb_map1 [10.4] (function version of map1, see ecgmap.h) + wfdb_setmap1 [10.4] (function version of setmap1, see ecgmap.h) + wfdb_map2 [10.4] (function version of map2, see ecgmap.h) + wfdb_setmap2 [10.4] (function version of setmap2, see ecgmap.h) + wfdb_ammap [10.4] (function version of ammap, see ecgmap.h) + wfdb_mamap [10.4] (function version of mamap, see ecgmap.h) + wfdb_annpos [10.4] (function version of annpos, see ecgmap.h) + wfdb_setannpos [10.4] (function version of setannpos, see ecgmap.h) (Numbers in brackets in the list above indicate the first version of the WFDB library that included the corresponding function. Functions not so marked @@ -55,8 +69,8 @@ These functions, also defined here, are intended only for the use of WFDB library functions defined elsewhere: - wfdb_anclose (closes all annotation files) - wfdb_oaflush (flushes output annotations) + wfdb_anclose (closes all annotation files) + wfdb_oaflush (flushes output annotations) Beginning with version 5.3, the functions in this file read and write annotation translation table modifications as `modification labels' (`NOTE' @@ -68,16 +82,12 @@ Simultaneous annotations attached to different signals (as indicated by the `chan' field) are supported by version 6.1 and later versions. Annotations must be written in time order; simultaneous annotations must be written in -`chan' order. Simultaneous annotations are readable but not writeable by +`chan' order. Simultaneous annotations are readable but not writable by earlier versions. */ #include "wfdblib.h" #include "ecgcodes.h" -#define isqrs -#define map1 -#define map2 -#define annpos #include "ecgmap.h" /* Annotation word format */ @@ -138,8 +148,7 @@ /* Local functions (for the use of other functions in this module only). */ -static int get_ann_table(i) -WFDB_Annotator i; +static int get_ann_table(WFDB_Annotator i) { char *p1, *p2, *s1, *s2; int a; @@ -183,8 +192,7 @@ setanndesc() has modified the mnemonic or description for annotation type i */ -static int put_ann_table(i) -WFDB_Annotator i; +static int put_ann_table(WFDB_Annotator i) { int a, flag = 0; char buf[256]; @@ -215,8 +223,7 @@ } /* Allocate workspace for up to n input annotators. */ -static int allociann(n) -unsigned n; +static int allociann(unsigned n) { if (maxiann < n) { /* allocate input annotator data structures */ unsigned m = maxiann; @@ -242,8 +249,7 @@ } /* Allocate workspace for up to n output annotators. */ -static int allocoann(n) -unsigned n; +static int allocoann(unsigned n) { if (maxoann < n) { /* allocate output annotator data structures */ unsigned m = maxoann; @@ -270,10 +276,8 @@ /* WFDB library functions (for general use). */ -FINT annopen(record, aiarray, nann) -char *record; -WFDB_Anninfo *aiarray; -unsigned int nann; +/* annopen: open annotation files for the specified record */ +FINT annopen(char *record, WFDB_Anninfo *aiarray, unsigned int nann) { int a; unsigned int i, niafneeded, noafneeded; @@ -402,9 +406,8 @@ return (0); } -FINT getann(n, annot) /* read an annotation from annotator n into *annot */ -WFDB_Annotator n; /* annotator number */ -WFDB_Annotation *annot; /* address of structure to be filled in */ +/* getann: read an annotation from annotator n into *annot */ +FINT getann(WFDB_Annotator n, WFDB_Annotation *annot) { int a, len; struct iadata *ia; @@ -518,9 +521,8 @@ return (0); } -FINT ungetann(n, annot) /* push back an annotation into an input stream */ -WFDB_Annotator n; /* annotator number */ -WFDB_Annotation *annot; /* address of annotation to be pushed back */ +/* ungetann: push back an annotation into an input stream */ +FINT ungetann(WFDB_Annotator n, WFDB_Annotation *annot) { if (n >= niaf || iad[n] == NULL) { wfdb_error("ungetann: annotator %d is not initialized\n", n); @@ -537,9 +539,8 @@ return (0); } -FINT putann(n, annot) /* write annotation at annot to annotator n */ -WFDB_Annotator n; /* annotator number */ -WFDB_Annotation *annot; /* address of annotation to be written */ +/* putann: write annotation at annot to annotator n */ +FINT putann(WFDB_Annotator n, WFDB_Annotation *annot) { unsigned annwd; char *ap; @@ -631,8 +632,9 @@ return (0); } -FINT iannsettime(t) -WFDB_Time t; +/* iannsettime: seek so that for the next annotation read from each input + annotator, anntime >= t */ +FINT iannsettime(WFDB_Time t) { int stat = 0; WFDB_Annotation tempann; @@ -667,6 +669,30 @@ return (stat); } +/* Functions for converting between anntyp values (annotation codes defined in + <ecgcode.h>), mnemonics (short strings, usually only one character), and + descriptive strings + + There are two sets of mnemonics (cstring[] and astring[]) and one set of + descriptive strings (tstring[]) defined below. The two sets of mnemonics + are identical by default. + + The conversion functions (ecgstr and annstr) translate the annotation code + specified by their argument into a mnemonic. Illegal or undefined codes are + translated into decimal numerals surrounded by brackets (e.g., `[55]'). The + mnemonics returned by annstr (those defined in astring[]) may be modified + either by setannstr or by the presence of modification labels in an input + annotation file. Those returned by ecgstr (defined in cstring[]) are + usually the same, but they can be modified only by setecgstr, and not by the + presence of modification labels as for annstr. The intent is that ecgstr + should be used rather than annstr only when it is necessary that a fixed set + of mnemonics be used, independent of any modification labels. The functions + strecg and annstr perform the inverse of these translations. + + The functions anndesc and setanndesc are similar to annstr and setannstr, + except that they use the descriptive strings (tstring[]). +*/ + static char *cstring[ACMAX+1] = { /* ECG mnemonics for each code */ " ", "N", "L", "R", "a", /* 0 - 4 */ "V", "F", "J", "A", "S", /* 5 - 9 */ @@ -680,8 +706,8 @@ "[45]", "[46]", "[47]", "[48]", "[49]" /* 45 - 49 */ }; -FSTRING ecgstr(code) -int code; +/* ecgstr: convert an anntyp value to a mnemonic string */ +FSTRING ecgstr(int code) { static char buf[9]; @@ -693,8 +719,8 @@ } } -FINT strecg(str) -char *str; +/* strecg: convert a mnemonic string to an anntyp value */ +FINT strecg(char *str) { int code; @@ -704,9 +730,8 @@ return (NOTQRS); } -FINT setecgstr(code, string) -int code; -char *string; +/* setecgstr: set the mnemonic string associated with the specified anntyp */ +FINT setecgstr(int code, char *string) { if (NOTQRS <= code && code <= ACMAX) { if (cstring[code] == NULL || strcmp(cstring[code], string)) { @@ -732,8 +757,7 @@ "[45]", "[46]", "[47]", "[48]", "[49]" /* 45 - 49 */ }; -FSTRING annstr(code) -int code; +FSTRING annstr(int code) { static char buf[9]; @@ -745,8 +769,7 @@ } } -FINT strann(str) -char *str; +FINT strann(char *str) { int code; @@ -756,9 +779,7 @@ return (NOTQRS); } -FINT setannstr(code, string) -int code; -char *string; +FINT setannstr(int code, char *string) { if (0 < code && code <= ACMAX) { if (astring[code] == NULL || strcmp(astring[code], string)) { @@ -836,8 +857,7 @@ (char *)NULL }; -FSTRING anndesc(code) -int code; +FSTRING anndesc(int code) { if (0 <= code && code <= ACMAX) return (tstring[code]); @@ -845,9 +865,7 @@ return ("illegal annotation code"); } -FINT setanndesc(code, string) -int code; -char *string; +FINT setanndesc(int code, char *string) { if (0 < code && code <= ACMAX) { if (tstring[code] == NULL || strcmp(tstring[code], string)) { @@ -872,8 +890,8 @@ } } -FVOID iannclose(n) /* close input annotation file n */ -WFDB_Annotator n; +/* iannclose: close input annotation file n */ +FVOID iannclose(WFDB_Annotator n) { struct iadata *ia; @@ -891,8 +909,9 @@ } } -FVOID oannclose(n) /* close output annotation file n */ -WFDB_Annotator n; + +/* oannclose: close output annotation file n */ +FVOID oannclose(WFDB_Annotator n) { int i; char cmdbuf[256]; @@ -950,9 +969,72 @@ } } +/* Semi-private functions + + These functions wrap the macros defined in <ecgmap.h>. They are + intended to simplify maintenance of WFDB wrappers generated using + SWIG, which cannot wrap macros automatically. +*/ + +FINT wfdb_isann(int code) +{ + return (isann(code)); +} + +FINT wfdb_isqrs(int code) +{ + return (isqrs(code)); +} + +FINT wfdb_setisqrs(int code, int newval) +{ + return (setisqrs(code, newval)); +} + +FINT wfdb_map1(int code) +{ + return (map1(code)); +} + +FINT wfdb_setmap1(int code, int newval) +{ + return (setmap1(code, newval)); +} + +FINT wfdb_map2(int code) +{ + return (map2(code)); +} + +FINT wfdb_setmap2(int code, int newval) +{ + return (setmap2(code, newval)); +} + +FINT wfdb_ammap(int code) +{ + return (ammap(code)); +} + +FINT wfdb_mamap(int code, int subtype) +{ + return (mamap(code, subtype)); +} + +FINT wfdb_annpos(int code) +{ + return (annpos(code)); +} + +FINT wfdb_setannpos(int code, int newval) +{ + return (setannpos(code, newval)); +} + + /* Private functions (for the use of other WFDB library functions only). */ -void wfdb_oaflush() +void wfdb_oaflush(void) { unsigned int i; @@ -960,7 +1042,7 @@ (void)wfdb_fflush(oad[i]->file); } -void wfdb_anclose() +void wfdb_anclose(void) { WFDB_Annotator an; diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/lib/calib.c wfdb-10.4.0/lib/calib.c --- wfdb-10.3.17/lib/calib.c 2002-06-02 08:51:36.000000000 -0400 +++ wfdb-10.4.0/lib/calib.c 2006-02-23 15:56:01.000000000 -0500 @@ -1,10 +1,10 @@ -/* file: calib.c G. Moody 4 July 1991 - Last revised: 2 June 2002 wfdblib 10.2.6 +/* file: calib.c G. Moody 4 July 1991 + Last revised: 23 February 2006 wfdblib 10.4.0 WFDB library functions for signal calibration _______________________________________________________________________________ wfdb: a library for reading and writing annotated waveforms (time series data) -Copyright (C) 2002 George B. Moody +Copyright (C) 1991-2006 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 @@ -67,8 +67,7 @@ otherwise, the "+" is discarded before attempting to open the file, which may be in any directory in the WFDB path. If the file can be read, its contents are appended to the calibration list. */ -FINT calopen(cfname) -char *cfname; +FINT calopen(char *cfname) { WFDB_FILE *cfile; char buf[128], *p1, *p2, *p3, *p4, *p5, *p6; @@ -170,10 +169,7 @@ of finding a match. If a match is found, it is copied into the caller's WFDB_Calinfo structure. The caller must not write over the storage addressed by the desc and units fields. */ -FINT getcal(desc, units, cal) -char *desc; /* signal description (or prefix) */ -char *units; /* signal units (or NULL) */ -WFDB_Calinfo *cal; /* WFDB_Calinfo structure to be filled in */ +FINT getcal(char *desc, char *units, WFDB_Calinfo *cal) { for (this_cle = first_cle; this_cle; this_cle = this_cle->next) { if ((desc == NULL || strncmp(desc, this_cle->sigtype, @@ -193,8 +189,7 @@ /* Function putcal appends the caller's WFDB_Calinfo structure to the end of the calibration list. */ -FINT putcal(cal) -WFDB_Calinfo *cal; /* WFDB_Calinfo record to be appended to list */ +FINT putcal(WFDB_Calinfo *cal) { #ifndef lint if ((this_cle = (struct cle *)malloc(sizeof(struct cle))) == NULL || @@ -230,8 +225,7 @@ /* Function newcal generates a calibration file based on the contents of the calibration list. */ -FINT newcal(cfname) /* name for new calibration file */ -char *cfname; +FINT newcal(char *cfname) { WFDB_FILE *cfile; @@ -271,7 +265,7 @@ } /* Function flushcal empties the calibration list. */ -FVOID flushcal() +FVOID flushcal(void) { while (first_cle) { free(first_cle->sigtype); diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/lib/Makefile.top wfdb-10.4.0/lib/Makefile.top --- wfdb-10.3.17/lib/Makefile.top 2002-10-26 14:55:22.000000000 -0400 +++ wfdb-10.4.0/lib/Makefile.top 2006-02-23 15:59:15.000000000 -0500 @@ -1,10 +1,10 @@ -# file: Makefile G. Moody 6 July 1983 -# Last revised: 26 October 2002 Version 10.2.9 +# file: Makefile G. Moody 6 July 1983 +# Last revised: 23 February 2006 wfdblib 10.4.0 # 'make' description file for compiling the WFDB library # # _____________________________________________________________________________ # wfdb: a library for reading and writing annotated waveforms(time series data) -# Copyright (C) 2000 George B. Moody +# Copyright (C) 1983-2006 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 diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/lib/Makefile.tpl wfdb-10.4.0/lib/Makefile.tpl --- wfdb-10.3.17/lib/Makefile.tpl 2005-08-08 07:23:41.000000000 -0400 +++ wfdb-10.4.0/lib/Makefile.tpl 2006-02-24 23:22:16.000000000 -0500 @@ -1,11 +1,9 @@ # file: Makefile.tpl G. Moody 24 May 2000 -# Last revised: 8 August 2005 +# Last revised: 24 February 2006 # This section of the Makefile should not need to be changed. INCLUDES = $(INCDIR)/wfdb/wfdb.h $(INCDIR)/wfdb/ecgcodes.h \ $(INCDIR)/wfdb/ecgmap.h -COMPAT_INCLUDES = $(INCDIR)/ecg/db.h $(INCDIR)/ecg/ecgcodes.h \ - $(INCDIR)/ecg/ecgmap.h HFILES = wfdb.h ecgcodes.h ecgmap.h wfdblib.h CFILES = wfdbinit.c annot.c signal.c calib.c wfdbio.c OFILES = wfdbinit.o annot.o signal.o calib.o wfdbio.o @@ -38,10 +36,6 @@ $(CC) $(CFLAGS) -DVERSION='"$(VERSION)"' -DCFLAGS='"$(CFLAGS)"' \ -DLDFLAGS='"$(LDFLAGS)"' -I$(INCDIR) -o $@ wfdb-config.c -# `make compat': install the includes needed for source compatibility with -# applications written for pre-version 10.0.0 versions of this library -compat: $(INCLUDES) $(COMPAT_INCLUDES) - # `make clean': also remove previously compiled versions of the library clean: rm -f $(OFILES) libwfdb.* *.dll *~ wfdb.h wfdblib.h wfdb-config @@ -76,14 +70,6 @@ cp -p ecgmap.h $(INCDIR)/wfdb $(SETPERMISSIONS) $(INCDIR)/wfdb/ecgmap.h -# Rules for installing the compatibility (pre-10.0.0) include files -$(INCDIR)/ecg/db.h: $(INCDIR)/ecg db.h - cp -p db.h $(INCDIR)/ecg; $(SETPERMISSIONS) $(INCDIR)/ecg/db.h -$(INCDIR)/ecg/ecgcodes.h: $(INCDIR)/ecg $(INCDIR)/wfdb/ecgcodes.h - ln -s $(INCDIR)/wfdb/ecgcodes.h $(INCDIR)/ecg/ecgcodes.h -$(INCDIR)/ecg/ecgmap.h: $(INCDIR)/ecg $(INCDIR)/wfdb/ecgmap.h - ln -s $(INCDIR)/wfdb/ecgmap.h $(INCDIR)/ecg/ecgmap.h - # Prerequisites for the library modules wfdbinit.o: wfdb.h wfdblib.h wfdbinit.c annot.o: wfdb.h ecgcodes.h ecgmap.h wfdblib.h annot.c diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/lib/signal.c wfdb-10.4.0/lib/signal.c --- wfdb-10.3.17/lib/signal.c 2005-08-12 01:48:43.000000000 -0400 +++ wfdb-10.4.0/lib/signal.c 2006-02-25 15:24:56.000000000 -0500 @@ -1,10 +1,10 @@ /* file: signal.c G. Moody 13 April 1989 - Last revised: 11 August 2005 wfdblib 10.3.17 + Last revised: 25 February 2006 wfdblib 10.4.0 WFDB library functions for signals _______________________________________________________________________________ wfdb: a library for reading and writing annotated waveforms (time series data) -Copyright (C) 1989-2005 George B. Moody +Copyright (C) 1989-2006 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 @@ -140,7 +140,7 @@ #if 0 /* This is sample code to show how to allocate signal information and sample vector arrays in an application -- it is *not* compiled into this module! */ -example() +void example(void) { int n, nsig, i, framelen; WFDB_Siginfo *si; @@ -273,6 +273,7 @@ } **igd; static WFDB_Sample *tvector; /* getvec workspace */ static WFDB_Sample *uvector; /* isgsettime workspace */ +static int tuvlen; /* lengths of tvector and uvector in samples */ static WFDB_Time istime; /* time of next input sample */ static int ibsize; /* default input buffer size */ static unsigned skewmax; /* max skew (frames) between any 2 signals */ @@ -283,6 +284,8 @@ static unsigned framelen; /* total number of samples per frame */ static int gvmode = -1; /* getvec mode (WFDB_HIGHRES or WFDB_LOWRES once initialized) */ +static int gvpad; /* getvec padding (if non-zero, replace invalid + samples with previous valid samples) */ static int gvc; /* getvec sample-within-frame counter */ WFDB_Sample *sbuf = NULL; /* buffer used by sample() */ static int sample_vflag; /* if non-zero, last value returned by sample() @@ -317,8 +320,7 @@ /* Local functions (not accessible outside this file). */ /* Allocate workspace for up to n input signals. */ -static int allocisig(n) -unsigned n; +static int allocisig(unsigned int n) { if (maxisig < n) { unsigned m = maxisig; @@ -344,8 +346,7 @@ } /* Allocate workspace for up to n input signal groups. */ -static int allocigroup(n) -unsigned n; +static int allocigroup(unsigned int n) { if (maxigroup < n) { unsigned m = maxigroup; @@ -371,8 +372,7 @@ } /* Allocate workspace for up to n output signals. */ -static int allocosig(n) -unsigned n; +static int allocosig(unsigned int n) { if (maxosig < n) { unsigned m = maxosig; @@ -398,8 +398,7 @@ } /* Allocate workspace for up to n output signal groups. */ -static int allocogroup(n) -unsigned n; +static int allocogroup(unsigned int n) { if (maxogroup < n) { unsigned m = maxogroup; @@ -424,8 +423,7 @@ return (maxogroup); } -static int isfmt(f) -int f; +static int isfmt(int f) { int i; static int fmt_list[WFDB_NFMTS] = WFDB_FMT_LIST; @@ -435,8 +433,7 @@ return (0); } -static int copysi(to, from) -WFDB_Siginfo *to, *from; +static int copysi(WFDB_Siginfo *to, WFDB_Siginfo *from) { if (to == NULL || from == NULL) return (0); *to = *from; @@ -509,7 +506,7 @@ int spf; } *smi; -static void sigmap_cleanup() +static void sigmap_cleanup(void) { int i; @@ -537,7 +534,7 @@ } } -static int make_vsd() +static int make_vsd(void) { int i; @@ -573,7 +570,7 @@ return (nvsig); } -static int sigmap_init() +static int sigmap_init(void) { int i, j, k, kmax, s; struct sigmapinfo *ps; @@ -667,18 +664,21 @@ ovec[i] = vector[i]; for (i = 0; i < tspf; i++) { + if (ovec[smi[i].index] == WFDB_INVALID_SAMPLE) + vector[i] = WFDB_INVALID_SAMPLE; + else { vector[i] = v = ovec[smi[i].index] * smi[i].scale + smi[i].offset; #if defined(WFDB_OVERFLOW_CHECK) if (((v > 0.0 && v - ovec[i]) > 1.0) || ((v - ovec[i]) < -1.0)) wfdb_error("sigmap: overflow detected\n"); #endif + } } } /* end of code for handling variable-layout records */ -static int readheader(record) -char *record; +static int readheader(char *record) { char linebuf[256], *p, *q; WFDB_Frequency f; @@ -1108,7 +1108,7 @@ return (s); /* return number of available signals */ } -static void hsdfree() +static void hsdfree(void) { struct hsdata *hs; @@ -1126,7 +1126,7 @@ maxhsig = 0; } -static void isigclose() +static void isigclose(void) { struct isdata *is; struct igdata *ig; @@ -1176,7 +1176,7 @@ hsdfree(); } -static void osigclose() +static void osigclose(void) { struct osdata *os; struct ogdata *og; @@ -1261,8 +1261,7 @@ #define w61(V,G) (w8(((V) >> 8), (G)), w8((V), (G))) #else -static int r16(g) -struct igdata *g; +static int r16(struct igdata *g) { int l, h; @@ -1271,16 +1270,13 @@ return ((int)((short)((h << 8) | (l & 0xff)))); } -static void w16(v, g) -WFDB_Sample v; -struct ogdata *g; +static void w16(WFDB_Sample v, struct ogdata *g) { w8(v, g); w8((v >> 8), g); } -static int r61(g) -struct igdata *g; +static int r61(struct igdata *g) { int l, h; @@ -1289,9 +1285,7 @@ return ((int)((short)((h << 8) | (l & 0xff)))); } -static void w61(v, g) -WFDB_Sample v; -struct ogdata *g; +static void w61(WFDB_Sample v, struct ogdata *g) { w8((v >> 8), g); w8(v, g); @@ -1304,8 +1298,9 @@ #define r160(G) ((r16(G) & 0xffff) - (1 << 15)) #define w160(V, G) (w16(((V) & 0xffff) + (1 << 15), G)) -static int r212(g) /* read and return the next sample from a format 212 */ -struct igdata *g; /* signal file (2 12-bit samples bit-packed in 3 bytes) */ +/* r212: read and return the next sample from a format 212 signal file + (2 12-bit samples bit-packed in 3 bytes) */ +static int r212(struct igdata *g) { int v; @@ -1322,9 +1317,8 @@ return (v); } -static void w212(v, g) /* write the next sample to a format 212 signal file */ -WFDB_Sample v; -struct ogdata *g; +/* w212: write the next sample to a format 212 signal file */ +static void w212(WFDB_Sample v, struct ogdata *g) { /* Samples are buffered here and written in pairs, as three bytes. */ switch (g->count++) { @@ -1337,8 +1331,9 @@ } } -static int r310(g) /* read and return the next sample from a format 310 */ -struct igdata *g; /* signal file (3 10-bit samples bit-packed in 4 bytes) */ +/* r310: read and return the next sample from a format 310 signal file + (3 10-bit samples bit-packed in 4 bytes) */ +static int r310(struct igdata *g) { int v; @@ -1357,9 +1352,8 @@ return (v); } -static void w310(v, g) /* write the next sample to a format 310 signal file */ -WFDB_Sample v; -struct ogdata *g; +/* w310: write the next sample to a format 310 signal file */ +static void w310(WFDB_Sample v, struct ogdata *g) { /* Samples are buffered here and written in groups of three, as two left-justified 15-bit words. */ @@ -1374,10 +1368,10 @@ } } -/* Note that formats 310 and 311 differ in the layout of the bit-packed data */ - -static int r311(g) /* read and return the next sample from a format 311 */ -struct igdata *g; /* signal file (3 10-bit samples bit-packed in 4 bytes) */ +/* r311: read and return the next sample from a format 311 signal file + (3 10-bit samples bit-packed in 4 bytes; note that formats 310 and 311 + differ in the layout of the bit-packed data) */ +static int r311(struct igdata *g) { int v; @@ -1397,9 +1391,8 @@ return (v); } -static void w311(v, g) /* write the next sample to a format 311 signal file */ -WFDB_Sample v; -struct ogdata *g; +/* w311: write the next sample to a format 311 signal file */ +static void w311(WFDB_Sample v, struct ogdata *g) { /* Samples are buffered here and written in groups of three, bit-packed into the 30 low bits of a 32-bit word. */ @@ -1414,9 +1407,7 @@ } } -static int isgsetframe(g, t) -WFDB_Group g; -WFDB_Time t; +static int isgsetframe(WFDB_Group g, WFDB_Time t) { int i, trem = 0; long nb, tt; @@ -1602,8 +1593,7 @@ return (0); } -static int getskewedframe(vector) -WFDB_Sample *vector; +static int getskewedframe(WFDB_Sample *vector) { int c, stat; struct isdata *is; @@ -1630,7 +1620,7 @@ for (c = 0; c < is->info.spf; c++, vector++) { switch (is->info.fmt) { case 0: /* null signal: return sample tagged as invalid */ - *vector = v = WFDB_INVALID_SAMPLE; + *vector = v = gvpad ? is->samp : WFDB_INVALID_SAMPLE; if (is->info.nsamp == 0) ig->stat = -1; break; case 8: /* 8-bit first differences */ @@ -1642,23 +1632,33 @@ *vector = v = r61(ig); break; case 80: /* 8-bit offset binary amplitudes */ *vector = v = r80(ig); - if (v == 0) *vector = WFDB_INVALID_SAMPLE; + if (v == -128) + *vector = gvpad ? is->samp : WFDB_INVALID_SAMPLE; + else + is->samp = *vector; break; case 160: /* 16-bit offset binary amplitudes */ - *vector = v = r160(ig); - if (v == 0) *vector = WFDB_INVALID_SAMPLE; - break; + *vector = v = r160(ig); break; case 212: /* 2 12-bit amplitudes bit-packed in 3 bytes */ *vector = v = r212(ig); - if (v == -2048) *vector = WFDB_INVALID_SAMPLE; + if (v == -2048) + *vector = gvpad ? is->samp : WFDB_INVALID_SAMPLE; + else + is->samp = *vector; break; case 310: /* 3 10-bit amplitudes bit-packed in 4 bytes */ *vector = v = r310(ig); - if (v == -512) *vector = WFDB_INVALID_SAMPLE; + if (v == -512) + *vector = gvpad ? is->samp : WFDB_INVALID_SAMPLE; + else + is->samp = *vector; break; case 311: /* 3 10-bit amplitudes bit-packed in 4 bytes */ *vector = v = r311(ig); - if (v == -512) *vector = WFDB_INVALID_SAMPLE; + if (v == -512) + *vector = gvpad ? is->samp : WFDB_INVALID_SAMPLE; + else + is->samp = *vector; break; } if (ig->stat <= 0) { @@ -1689,11 +1689,11 @@ else stat = -1; } - else - is->info.cksum -= v; + is->info.cksum -= v; } if (--is->info.nsamp == (WFDB_Time)0L && (is->info.cksum & 0xffff) && + !in_msrec && is->info.fmt != 0) { wfdb_error("getvec: checksum error in signal %d\n", s); stat = -4; @@ -1702,8 +1702,7 @@ return (stat); } -static int rgetvec(vector) -WFDB_Sample *vector; +static int rgetvec(WFDB_Sample *vector) { WFDB_Sample *tp; WFDB_Signal s; @@ -1745,10 +1744,7 @@ /* WFDB library functions. */ -FINT isigopen(record, siarray, nsig) -char *record; -WFDB_Siginfo *siarray; -int nsig; +FINT isigopen(char *record, WFDB_Siginfo *siarray, int nsig) { int navail, ngroups, nn; struct hsdata *hs; @@ -1906,12 +1902,14 @@ framelen += isd[si]->info.spf; /* Allocate workspace for getvec and isgsettime. */ - if ((tvector = calloc(sizeof(WFDB_Sample), framelen)) == NULL || - (uvector = calloc(sizeof(WFDB_Sample), framelen)) == NULL) { + if (framelen > tuvlen && + ((tvector = realloc(tvector, sizeof(WFDB_Sample)*framelen)) == NULL || + (uvector = realloc(uvector, sizeof(WFDB_Sample)*framelen)) == NULL)) { wfdb_error("isigopen: can't allocate frame buffer\n"); if (tvector) (void)free(tvector); return (-3); } + tuvlen = framelen; /* If deskewing is required, allocate the deskewing buffer (unless this is a multi-segment record and dsbuf has been allocated already). */ @@ -1927,10 +1925,7 @@ return (s); } -FINT osigopen(record, siarray, nsig) -char *record; -WFDB_Siginfo *siarray; -unsigned int nsig; +FINT osigopen(char *record, WFDB_Siginfo *siarray, unsigned int nsig) { int n; struct osdata *os, *op; @@ -2022,9 +2017,7 @@ return (s); } -FINT osigfopen(siarray, nsig) -WFDB_Siginfo *siarray; -unsigned int nsig; +FINT osigfopen(WFDB_Siginfo *siarray, unsigned int nsig) { struct osdata *os, *op; struct ogdata *og; @@ -2171,13 +2164,12 @@ this problem. */ -FINT getspf() +FINT getspf(void) { return ((sfreq != ffreq) ? (int)(sfreq/ffreq + 0.5) : 1); } -FVOID setgvmode(mode) -int mode; +FVOID setgvmode(int mode) { if (mode < 0) { /* (re)set to default mode */ char *p; @@ -2188,7 +2180,7 @@ mode = DEFWFDBGVMODE; } - if (mode == WFDB_HIGHRES) { + if ((mode & WFDB_HIGHRES) == WFDB_HIGHRES) { gvmode = WFDB_HIGHRES; sfreq = ffreq * ispfmax; } @@ -2196,6 +2188,10 @@ gvmode = WFDB_LOWRES; sfreq = ffreq; } + if ((mode & WFDB_GVPAD) == WFDB_GVPAD) + gvpad = 1; + else + gvpad = 0; } /* An application can specify the input sampling frequency it prefers by @@ -2206,8 +2202,7 @@ static WFDB_Time rgvtime, gvtime; static WFDB_Sample *gv0, *gv1; -FINT setifreq(f) -WFDB_Frequency f; +FINT setifreq(WFDB_Frequency f) { if (f > 0.0) { WFDB_Frequency error, g = sfreq; @@ -2258,8 +2253,7 @@ return (ifreq > (WFDB_Frequency)0 ? ifreq : sfreq); } -FINT getvec(vector) -WFDB_Sample *vector; +FINT getvec(WFDB_Sample *vector) { int i; @@ -2285,8 +2279,7 @@ return (rgvstat); } -FINT getframe(vector) -WFDB_Sample *vector; +FINT getframe(WFDB_Sample *vector) { int stat; @@ -2318,8 +2311,7 @@ return (stat); } -FINT putvec(vector) -WFDB_Sample *vector; +FINT putvec(WFDB_Sample *vector) { int c, dif, stat = (int)nosig; struct osdata *os; @@ -2389,8 +2381,7 @@ return (stat); } -FINT isigsettime(t) -WFDB_Time t; +FINT isigsettime(WFDB_Time t) { WFDB_Group g; int stat = 0; @@ -2407,9 +2398,7 @@ return (stat); } -FINT isgsettime(g, t) -WFDB_Group g; -WFDB_Time t; +FINT isgsettime(WFDB_Group g, WFDB_Time t) { int spf, stat, tr, trem = 0; @@ -2456,8 +2445,7 @@ return (stat); } -FINT setibsize(n) -int n; +FINT setibsize(int n) { if (nisig) { wfdb_error("setibsize: can't change buffer size after isigopen\n"); @@ -2471,8 +2459,7 @@ return (ibsize = n); } -FINT setobsize(n) -int n; +FINT setobsize(int n) { if (nosig) { wfdb_error("setobsize: can't change buffer size after osig[f]open\n"); @@ -2486,8 +2473,7 @@ return (obsize = n); } -FINT newheader(record) -char *record; +FINT newheader(char *record) { int stat; WFDB_Signal s; @@ -2512,10 +2498,7 @@ return (stat); } -FINT setheader(record, siarray, nsig) -char *record; -WFDB_Siginfo *siarray; -unsigned int nsig; +FINT setheader(char *record, WFDB_Siginfo *siarray, unsigned int nsig) { char *p; WFDB_Signal s; @@ -2587,9 +2570,7 @@ return (0); } -FINT setmsheader(record, segment_name, nsegments) -char *record, *segment_name[]; -unsigned nsegments; +FINT setmsheader(char *record, char **segment_name, unsigned int nsegments) { WFDB_Frequency msfreq, mscfreq; double msbcount; @@ -2706,8 +2687,7 @@ return (0); } -FINT wfdbgetskew(s) -WFDB_Signal s; +FINT wfdbgetskew(WFDB_Signal s) { if (s < nisig) return (vsd[s]->skew); @@ -2717,9 +2697,7 @@ /* Careful!! This function is dangerous, and should be used only to restore skews when they have been reset as a side effect of using, e.g., sampfreq */ -FVOID wfdbsetiskew(s, skew) -WFDB_Signal s; -int skew; +FVOID wfdbsetiskew(WFDB_Signal s, int skew) { if (s < nisig) vsd[s]->skew = skew; @@ -2728,16 +2706,13 @@ /* Note: wfdbsetskew affects *only* the skew to be written by setheader. It does not affect how getframe deskews input signals, nor does it affect the value returned by wfdbgetskew. */ -FVOID wfdbsetskew(s, skew) -WFDB_Signal s; -int skew; +FVOID wfdbsetskew(WFDB_Signal s, int skew) { if (s < nosig) osd[s]->skew = skew; } -FLONGINT wfdbgetstart(s) -WFDB_Signal s; +FLONGINT wfdbgetstart(WFDB_Signal s) { if (s < nisig) return (igd[vsd[s]->info.group]->start); @@ -2748,17 +2723,14 @@ /* Note: wfdbsetstart affects *only* the byte offset to be written by setheader. It does not affect how isgsettime calculates byte offsets, nor does it affect the value returned by wfdbgetstart. */ -FVOID wfdbsetstart(s, bytes) -WFDB_Signal s; -long bytes; +FVOID wfdbsetstart(WFDB_Signal s, long int bytes) { if (s < nosig) ogd[osd[s]->info.group]->start = bytes; prolog_bytes = bytes; } -FSTRING getinfo(record) -char *record; +FSTRING getinfo(char *record) { char *p; static char linebuf[256]; @@ -2785,8 +2757,7 @@ return (linebuf+1); } -FINT putinfo(s) -char *s; +FINT putinfo(char *s) { if (oheader == NULL) { wfdb_error( @@ -2798,8 +2769,7 @@ return (0); } -FFREQUENCY sampfreq(record) -char *record; +FFREQUENCY sampfreq(char *record) { int n; @@ -2818,8 +2788,7 @@ return (sfreq); } -FINT setsampfreq(freq) -WFDB_Frequency freq; +FINT setsampfreq(WFDB_Frequency freq) { if (freq >= 0.) { sfreq = ffreq = freq; @@ -2839,8 +2808,7 @@ #endif #endif -FINT setbasetime(string) -char *string; +FINT setbasetime(char *string) { char *p; @@ -2874,8 +2842,7 @@ return (0); } -FSTRING timstr(t) -WFDB_Time t; +FSTRING timstr(WFDB_Time t) { char *p; @@ -2889,8 +2856,7 @@ static WFDB_Date pdays = -1; -FSTRING mstimstr(t) -WFDB_Time t; +FSTRING mstimstr(WFDB_Time t) { double f; int hours, minutes, seconds, msec; @@ -2945,30 +2911,27 @@ return (time_string); } -FFREQUENCY getcfreq() +FFREQUENCY getcfreq(void) { return (cfreq > 0. ? cfreq : ffreq); } -FVOID setcfreq(freq) -WFDB_Frequency freq; +FVOID setcfreq(WFDB_Frequency freq) { cfreq = freq; } -FDOUBLE getbasecount() +FDOUBLE getbasecount(void) { return (bcount); } -FVOID setbasecount(counter) -double counter; +FVOID setbasecount(double counter) { bcount = counter; } -FSITIME strtim(string) -char *string; +FSITIME strtim(char *string) { char *p; double f, x, y, z; @@ -3015,8 +2978,7 @@ based on similar functions in chapter 1 of "Numerical Recipes", by Press, Flannery, Teukolsky, and Vetterling (Cambridge U. Press, 1986). */ -FSTRING datstr(date) -WFDB_Date date; +FSTRING datstr(WFDB_Date date) { int d, m, y, gcorr, jm, jy; long jd; @@ -3038,8 +3000,7 @@ return (date_string); } -FDATE strdat(string) -char *string; +FDATE strdat(char *string) { char *mp, *yp; int d, m, y, gcorr, jm, jy; @@ -3061,9 +3022,7 @@ return (date); } -FINT adumuv(s, a) -WFDB_Signal s; -WFDB_Sample a; +FINT adumuv(WFDB_Signal s, WFDB_Sample a) { double x; WFDB_Gain g = (s < nvsig) ? vsd[s]->info.gain : WFDB_DEFGAIN; @@ -3076,9 +3035,7 @@ return ((int)(x - 0.5)); } -FSAMPLE muvadu(s, v) -WFDB_Signal s; -int v; +FSAMPLE muvadu(WFDB_Signal s, int v) { double x; WFDB_Gain g = (s < nvsig) ? vsd[s]->info.gain : WFDB_DEFGAIN; @@ -3091,9 +3048,7 @@ return ((int)(x - 0.5)); } -FDOUBLE aduphys(s, a) -WFDB_Signal s; -WFDB_Sample a; +FDOUBLE aduphys(WFDB_Signal s, WFDB_Sample a) { int b; WFDB_Gain g; @@ -3110,9 +3065,7 @@ return ((a - b)/g); } -FSAMPLE physadu(s, v) -WFDB_Signal s; -double v; +FSAMPLE physadu(WFDB_Signal s, double v) { int b; WFDB_Gain g; @@ -3136,17 +3089,17 @@ /* sample(s, t) provides buffered random access to the input signals. The arguments are the signal number (s) and the sample number (t); the returned value is the sample from signal s at time t. On return, the global variable -sample_vflag is true (non-zero) if the returned value is valid, false (zero) -otherwise. The caller must open the input signals and must set the global -variable nisig to the number of input signals before invoking sample(). Once -this has been done, the caller may request samples in any order. */ +sample_vflag is true (non-zero) if the requested sample is not beyond the end +of the record, false (zero) otherwise. The caller must open the input signals +and must set the global variable nisig to the number of input signals before +invoking sample(). Once this has been done, the caller may request samples in +any order. */ #define BUFLN 4096 /* must be a power of 2, see sample() */ -FSAMPLE sample(s, t) -WFDB_Signal s; -WFDB_Time t; +FSAMPLE sample(WFDB_Signal s, WFDB_Time t) { + static WFDB_Sample v; static WFDB_Time tt; /* Allocate the sample buffer on the first call. */ @@ -3158,7 +3111,20 @@ exit(2); } } + + /* 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) { + sample_vflag = -1; + return (WFDB_INVALID_SAMPLE); + } + + /* If the caller specified a negative sample number, prepare to return + sample 0. This behavior differs from the convention that only the + absolute value of the sample number matters. */ if (t < 0L) t = 0L; + /* If the caller has requested a sample that is no longer in the buffer, or if the caller has requested a sample that is further ahead than the length of the buffer, we need to reset the signal file pointer(s). @@ -3179,20 +3145,24 @@ sample_vflag = 0; return (*(sbuf + nisig * (tt&(BUFLN-1)) + s)); } + /* The requested sample is in the buffer. Set sample_vflag and return the requested sample. */ - sample_vflag = 1; - return (*(sbuf + nisig * (t&(BUFLN-1)) + s)); + if ((v = *(sbuf + nisig * (t&(BUFLN-1)) + s)) == WFDB_INVALID_SAMPLE) + sample_vflag = -1; + else + sample_vflag = 1; + return (v); } -FINT sample_valid() +FINT sample_valid(void) { return (sample_vflag); } /* Private functions (for use by other WFDB library functions only). */ -void wfdb_sampquit() +void wfdb_sampquit(void) { if (sbuf) { (void)free(sbuf); @@ -3201,7 +3171,7 @@ } } -void wfdb_sigclose() +void wfdb_sigclose(void) { isigclose(); osigclose(); @@ -3232,12 +3202,15 @@ } if (gv0) (void)free(gv0); if (gv1) (void)free(gv1); - gv0 = gv1 = NULL; + if (tvector) (void)free(tvector); + if (uvector) (void)free(uvector); + tuvlen = 0; + gv0 = gv1 = tvector = uvector = NULL; sigmap_cleanup(); } -void wfdb_osflush() +void wfdb_osflush(void) { WFDB_Group g; struct ogdata *og; diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/lib/wfdb-config.c wfdb-10.4.0/lib/wfdb-config.c --- wfdb-10.3.17/lib/wfdb-config.c 2002-06-17 19:07:26.000000000 -0400 +++ wfdb-10.4.0/lib/wfdb-config.c 2006-02-23 17:48:10.000000000 -0500 @@ -1,8 +1,9 @@ /* file: wfdb-config.c G. Moody 27 April 2002 + Last revised: 23 February 2006 wfdblib 10.4.0 ------------------------------------------------------------------------------- wfdb-config: Print WFDB library version and linking information -Copyright (C) 2002 George B. Moody +Copyright (C) 2002-2006 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 @@ -45,13 +46,11 @@ char *pname; -main(argc, argv) -int argc; -char *argv[]; +main(int argc, char **argv) { - char *filename, *prog_name(); + char *filename, *prog_name(char *s); int i; - void help(); + void help(void); pname = prog_name(argv[0]); if (argc == 1) { @@ -72,8 +71,7 @@ exit(0); } -char *prog_name(s) -char *s; +char *prog_name(char *s) { char *p = s + strlen(s); @@ -97,7 +95,7 @@ NULL }; -void help() +void help(void) { int i; diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/lib/wfdb.h0 wfdb-10.4.0/lib/wfdb.h0 --- wfdb-10.3.17/lib/wfdb.h0 2005-07-01 20:42:41.000000000 -0400 +++ wfdb-10.4.0/lib/wfdb.h0 2006-02-25 15:15:53.000000000 -0500 @@ -1,10 +1,10 @@ /* file: wfdb.h G. Moody 13 June 1983 - Last revised: 1 July 2005 wfdblib 10.3.17 + Last revised: 25 February 2006 wfdblib 10.4.0 WFDB library type, constant, structure, and function interface definitions _______________________________________________________________________________ wfdb: a library for reading and writing annotated waveforms (time series data) -Copyright (C) 1983-2005 George B. Moody +Copyright (C) 1983-2006 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 @@ -32,8 +32,8 @@ /* WFDB library version. */ #define WFDB_MAJOR 10 -#define WFDB_MINOR 3 -#define WFDB_RELEASE 17 +#define WFDB_MINOR 4 +#define WFDB_RELEASE 0 #define WFDB_NETFILES 1 /* if 1, library includes code for HTTP, FTP clients */ #define WFDB_NETFILES_LIBCURL 1 @@ -126,6 +126,9 @@ #define WFDB_LOWRES 0 /* return one sample per signal per frame */ #define WFDB_HIGHRES 1 /* return each sample of oversampled signals, duplicating samples of other signals */ +#define WFDB_GVPAD 2 /* replace invalid samples with previous valid + samples */ + /* calinfo '.caltype' values WFDB_AC_COUPLED and WFDB_DC_COUPLED are used in combination with the pulse shape definitions below to characterize calibration pulses. */ @@ -259,6 +262,17 @@ extern FINT setanndesc(int annotation_code, char *annotation_description); extern FVOID iannclose(WFDB_Annotator a); extern FVOID oannclose(WFDB_Annotator a); +extern FINT wfdb_isann(int code); +extern FINT wfdb_isqrs(int code); +extern FINT wfdb_setisqrs(int code, int newval); +extern FINT wfdb_map1(int code); +extern FINT wfdb_setmap1(int code, int newval); +extern FINT wfdb_map2(int code); +extern FINT wfdb_setmap2(int code, int newval); +extern FINT wfdb_ammap(int code); +extern FINT wfdb_mamap(int code, int subtype); +extern FINT wfdb_annpos(int code); +extern FINT wfdb_setannpos(int code, int newval); extern FSTRING timstr(WFDB_Time t); extern FSTRING mstimstr(WFDB_Time t); extern FSITIME strtim(char *time_string); @@ -269,7 +283,7 @@ extern FDOUBLE aduphys(WFDB_Signal s, WFDB_Sample a); extern FSAMPLE physadu(WFDB_Signal s, double v); extern FSAMPLE sample(WFDB_Signal s, WFDB_Time t); -extern FINT sample_valid(); +extern FINT sample_valid(void); extern FINT calopen(char *calibration_filename); extern FINT getcal(char *description, char *units, WFDB_Calinfo *cal); extern FINT putcal(WFDB_Calinfo *cal); @@ -281,6 +295,7 @@ extern FINT setheader(char *record, WFDB_Siginfo *siarray, unsigned int nsig); extern FINT setmsheader(char *record, char **segnames, unsigned int nsegments); extern FINT wfdbgetskew(WFDB_Signal s); +extern FVOID wfdbsetiskew(WFDB_Signal s, int skew); extern FVOID wfdbsetskew(WFDB_Signal s, int skew); extern FLONGINT wfdbgetstart(WFDB_Signal s); extern FVOID wfdbsetstart(WFDB_Signal s, long bytes); @@ -311,7 +326,10 @@ extern FINT annopen(), isigopen(), osigopen(), wfdbinit(), getspf(), setifreq(), getvec(), getframe(), putvec(), getann(), ungetann(), putann(), isigsettime(), isgsettime(), iannsettime(), strecg(), setecgstr(), - strann(), setannstr(), setanndesc(), adumuv(), newheader(), setheader(), + strann(), setannstr(), setanndesc(), wfdb_isann(), wfdb_isqrs(), + wfdb_setisqrs(), wfdb_map1(), wfdb_setmap1(), wfdb_map2(), wfdb_setmap2(), + wfdb_ammap(), wfdb_mamap(), wfdb_annpos(), wfdb_setannpos(), + adumuv(), newheader(), setheader(), setmsheader(), setsampfreq(), setbasetime(), putinfo(), setibsize(), setobsize(), calopen(), getcal(), putcal(), newcal(), wfdbgetskew(), sample_valid(); @@ -322,8 +340,8 @@ extern FSITIME strtim(); extern FDATE strdat(); extern FVOID setgvmode(), wfdbquit(), wfdbquiet(), dbverbose(), setdb(), - wfdbflush(), setcfreq(), setbasecount(), flushcal(), wfdbsetskew(), - wfdbsetstart(); + wfdbflush(), setcfreq(), setbasecount(), flushcal(), wfdbsetiskew(), + wfdbsetskew(), wfdbsetstart(); extern FFREQUENCY getifreq(), sampfreq(), getcfreq(); extern FDOUBLE aduphys(), getbasecount(); #endif diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/lib/wfdbinit.c wfdb-10.4.0/lib/wfdbinit.c --- wfdb-10.3.17/lib/wfdbinit.c 2003-04-07 10:28:52.000000000 -0400 +++ wfdb-10.4.0/lib/wfdbinit.c 2006-02-23 19:27:07.000000000 -0500 @@ -1,9 +1,9 @@ /* file: wfdbinit.c G. Moody 23 May 1983 - Last revised: 7 April 2003 wfdblib 10.3.6 + Last revised: 23 February 2006 wfdblib 10.4.0 WFDB library functions wfdbinit, wfdbquit, and wfdbflush _______________________________________________________________________________ wfdb: a library for reading and writing annotated waveforms (time series data) -Copyright (C) 2003 George B. Moody +Copyright (C) 1983-2006 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 @@ -32,11 +32,8 @@ #include "wfdblib.h" -FINT wfdbinit(record, aiarray, nann, siarray, nsig) -char *record; /* record name */ -WFDB_Anninfo *aiarray; /* annotation file information array */ -WFDB_Siginfo *siarray; /* signal information array */ -unsigned int nann, nsig; /* number of entries in afarray and siarray */ +FINT wfdbinit(char *record, WFDB_Anninfo *aiarray, unsigned int nann, + WFDB_Siginfo *siarray, unsigned int nsig) { int stat; @@ -45,17 +42,17 @@ return (stat); } -FVOID wfdbquit() +FVOID wfdbquit(void) { wfdb_anclose(); /* close annotation files, reset variables */ wfdb_sigclose(); /* close signals, reset variables */ wfdb_sampquit(); /* release sample data buffer */ #if WFDB_NETFILES - wfdb_wwwquit(); /* release any resources allocated by libwww */ + wfdb_wwwquit(); /* release resources allocated by libcurl or libwww */ #endif } -FVOID wfdbflush() /* write all buffered output to files */ +FVOID wfdbflush(void) /* write all buffered output to files */ { wfdb_oaflush(); /* flush buffered output annotations */ wfdb_osflush(); /* flush buffered output samples */ diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/lib/wfdbio.c wfdb-10.4.0/lib/wfdbio.c --- wfdb-10.3.17/lib/wfdbio.c 2005-06-11 23:26:01.000000000 -0400 +++ wfdb-10.4.0/lib/wfdbio.c 2006-02-23 18:53:52.000000000 -0500 @@ -1,10 +1,10 @@ /* file: wfdbio.c G. Moody 18 November 1988 - Last revised: 11 June 2005 wfdblib 10.3.16 + Last revised: 23 February 2006 wfdblib 10.4.0 Low-level I/O functions for the WFDB library _______________________________________________________________________________ wfdb: a library for reading and writing annotated waveforms (time series data) -Copyright (C) 1988-2005 George B. Moody +Copyright (C) 1988-2006 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 @@ -67,8 +67,8 @@ These functions, defined here if WFDB_NETFILES is non-zero, are intended only for the use of the functions in the next group below (except for wfdb_wwwquit, their definitions are not visible outside of this file): - wfdb_wwwquit * (shut down libwww cleanly) - www_init (initialize libwww) + wfdb_wwwquit * (shut down libcurl or libwww cleanly) + www_init (initialize libcurl or libwww) www_get_cont_len (find length of data for a given url) www_get_url_range_chunk (get a block of data from a given url) www_get_url_chunk (get all data from a given url) @@ -93,22 +93,22 @@ * wfdb_wwwquit is available outside of this file; it is invoked by wfdbquit (defined in wfdbinit.c) to permit an application to release resources used -by libwww before exiting. wfdb_wwwquit is also registered (by www_init) as a -function to be invoked on exit from an application, so it is not necessary -for applications to invoke wfdb_wwwquit (or wfdbquit) explicitly. +by libcurl or libwww before exiting. wfdb_wwwquit is also registered (by +www_init) as a function to be invoked on exit from an application, so it is not +necessary for applications to invoke wfdb_wwwquit (or wfdbquit) explicitly. In the current version of the WFDB library, output to remote files is not implemented; for this reason, several of the functions listed above are stubs (placeholders) only, as noted. These functions, also defined here, are compiled only if WFDB_NETFILES is non- -zero; they permit access to remote files via http or ftp (using libwww) as well -as to local files (using the standard C I/O functions). The functions in this -group are intended primarily for use by other WFDB library functions, but may -also be called directly by WFDB applications that need to read remote files. -Unlike other private functions in the WFDB library, the interfaces to these -are not likely to change, since they are designed to emulate the -similarly-named ANSI/ISO C standard I/O functions: +zero; they permit access to remote files via http or ftp (using libcurl or +libwww) as well as to local files (using the standard C I/O functions). The +functions in this group are intended primarily for use by other WFDB library +functions, but may also be called directly by WFDB applications that need to +read remote files. Unlike other private functions in the WFDB library, the +interfaces to these are not likely to change, since they are designed to +emulate the similarly-named ANSI/ISO C standard I/O functions: wfdb_clearerr (emulates clearerr) wfdb_feof (emulates feof) wfdb_ferror (emulates ferror) @@ -161,10 +161,10 @@ static char *wfdbpath; -FSTRING getwfdb() +FSTRING getwfdb(void) { if (wfdbpath == NULL) { - char *p = getenv("WFDB"), *wfdb_getiwfdb(); + char *p = getenv("WFDB"), *wfdb_getiwfdb(char *p); if (p == NULL) p = DEFWFDB; if (*p == '@') p = wfdb_getiwfdb(p); @@ -175,10 +175,9 @@ /* setwfdb can be called within an application to change the WFDB path. */ -FVOID setwfdb(p) -char *p; +FVOID setwfdb(char *p) { - void wfdb_export_config(); + void wfdb_export_config(void); if (p == NULL && (p = getenv("WFDB")) == NULL) p = DEFWFDB; wfdb_parse_path(p); @@ -191,14 +190,14 @@ static int error_print = 1; -FVOID wfdbquiet() +FVOID wfdbquiet(void) { error_print = 0; } /* wfdbverbose enables error messages from the WFDB library. */ -FVOID wfdbverbose() +FVOID wfdbverbose(void) { error_print = 1; } @@ -208,8 +207,7 @@ /* wfdbfile returns the pathname or URL of a WFDB file. */ -FSTRING wfdbfile(s, record) -char *s, *record; +FSTRING wfdbfile(char *s, char *record) { WFDB_FILE *ifile; @@ -237,8 +235,8 @@ 16 bits, it may be necessary to rewrite wfdb_g16() to obtain proper sign extension. */ -int wfdb_g16(fp) /* read a 16-bit integer in PDP-11 format */ -WFDB_FILE *fp; +/* read a 16-bit integer in PDP-11 format */ +int wfdb_g16(WFDB_FILE *fp) { int x; @@ -246,8 +244,8 @@ return ((int)((short)((wfdb_getc(fp) << 8) | (x & 0xff)))); } -long wfdb_g32(fp) /* read a 32-bit integer in PDP-11 format */ -WFDB_FILE *fp; +/* read a 32-bit integer in PDP-11 format */ +long wfdb_g32(WFDB_FILE *fp) { long x, y; @@ -256,17 +254,15 @@ return ((x << 16) | (y & 0xffff)); } -void wfdb_p16(x, fp) /* write a 16-bit integer in PDP-11 format */ -unsigned int x; -WFDB_FILE *fp; +/* write a 16-bit integer in PDP-11 format */ +void wfdb_p16(unsigned int x, WFDB_FILE *fp) { (void)wfdb_putc((char)x, fp); (void)wfdb_putc((char)(x >> 8), fp); } -void wfdb_p32(x, fp) /* write a 32-bit integer in PDP-11 format */ -long x; -WFDB_FILE *fp; +/* write a 32-bit integer in PDP-11 format */ +void wfdb_p32(long x, WFDB_FILE *fp) { wfdb_p16((unsigned int)(x >> 16), fp); wfdb_p16((unsigned int)x, fp); @@ -280,9 +276,8 @@ static struct wfdb_path_component *wfdb_path_list; /* wfdb_free_path_list clears out the path list, freeing all memory allocated -to it. */ - -void wfdb_free_path_list() + to it. */ +void wfdb_free_path_list(void) { struct wfdb_path_component *c0 = NULL, *c1 = wfdb_path_list; @@ -298,13 +293,25 @@ /* Operating system and compiler dependent code All of the operating system and compiler dependencies in the WFDB library are -contained within the following section of this file. (In the following -comments, 'MS-DOS' includes all versions of MS-Windows.) +contained within the following section of this file. There are three +significant types of platforms addressed here: + + UNIX and variants + This includes GNU/Linux, FreeBSD, Solaris, HP-UX, IRIX, AIX, and other + versions of UNIX, as well as Mac OS/X and Cygwin/MS-Windows. + MS-DOS and variants + This group includes MS-DOS, DR-DOS, OS/2, and all versions of MS-Windows + when using the native MS-Windows libraries (as when compiling with MinGW + gcc). + MacOS 9 and earlier + "Classic" MacOS. + +Differences among these platforms: 1. Directory separators vary: - UNIX and variants use `/'. + UNIX and variants (including Mac OS/X and Cygwin) use `/'. MS-DOS and OS/2 use `\'. - MacOS uses `:'. + MacOS 9 and earlier uses `:'. 2. Path component separators also vary: UNIX and variants use `:' (as in the PATH environment variable) @@ -355,7 +362,7 @@ #define RB "rb" #define WB "wb" -/* For all other C compilers, including most UNIX C compilers. */ +/* For all other C compilers, including traditional UNIX C compilers. */ # else #define DSEP '/' #define PSEP ':' @@ -367,8 +374,7 @@ /* wfdb_parse_path constructs a linked list of path components by splitting its string input (usually the value of WFDB). */ -int wfdb_parse_path(p) -char *p; +int wfdb_parse_path(char *p) { char *q; int current_type, found_end; @@ -449,8 +455,7 @@ #define SEEK_END 2 #endif -char *wfdb_getiwfdb(p) -char *p; +char *wfdb_getiwfdb(char *p) { FILE *wfdbpfile; int i = 0; @@ -485,7 +490,7 @@ #ifndef HAS_PUTENV #define wfdb_export_config() #else -void wfdb_export_config() +void wfdb_export_config(void) { char *p; @@ -525,8 +530,7 @@ path. This feature may be particularly useful to MS-DOS users because of that system's limit on the length of environment variables. */ -void wfdb_addtopath(s) -char *s; +void wfdb_addtopath(char *s) { char *d, *p, *t; int i, j, l; @@ -586,9 +590,9 @@ The first version is compiled by ANSI C compilers. (A variant of this version of wfdb_error can be used with Microsoft Windows; it puts the error message into a message box, rather than using the standard error output.) The second -version is compiled by modern UNIX C compilers (System V, Berkeley 4.x) that -are not ANSI-conforming. The third version can be compiled by many older C -compilers, if the symbol OLDC is defined; do so only if you are using a C +version is compiled by traditional UNIX C compilers (System V, Berkeley 4.x) +that are not ANSI-conforming. The third version can be compiled by many older +C compilers, if the symbol OLDC is defined; do so only if you are using a C library which does not include a vsprintf function and a "stdarg.h" or "varargs.h" header file. This third version uses an undocumented function (_doprnt) which works for most if not all older UNIX C compilers, and several @@ -604,7 +608,7 @@ static char error_message[256]; #endif -FSTRING wfdberror() +FSTRING wfdberror(void) { if (*error_message == '\0') sprintf(error_message, @@ -666,7 +670,7 @@ } #else -#ifndef OLDC /* Second version: for modern UNIX K&R C compilers */ +#ifndef OLDC /* Second version: for traditional UNIX K&R C compilers */ #include <varargs.h> void wfdb_error(va_alist) va_dcl @@ -792,9 +796,7 @@ than MS-DOS used file names in the format TYPE.RECORD. This file name format is no longer supported. */ -WFDB_FILE *wfdb_open(s, record, mode) -char *s, *record; -int mode; +WFDB_FILE *wfdb_open(char *s, char *record, int mode) { char *wfdb, *p; struct wfdb_path_component *c0; @@ -915,8 +917,7 @@ and they must contain only letters, digits, tildes, underscores, and directory separators. */ -int wfdb_checkname(p, s) -char *p, *s; +int wfdb_checkname(char *p, char *s) { do { if (('0' <= *p && *p <= '9') || *p == '_' || *p == '~' || *p == DSEP || @@ -939,8 +940,7 @@ recursively to open a segment within a multi-segment record) and by annopen (when it is about to open a file for input). */ -void wfdb_setirec(p) -char *p; +void wfdb_setirec(char *p) { char *r; @@ -955,16 +955,15 @@ /* WFDB file I/O functions -The WFDB library normally reads and writes local files. If libwww -(see http://www.w3.org/Library for details) is available, and if you compile -the WFDB library using an ANSI/ISO C compiler (not an older K&R C compiler), +The WFDB library normally reads and writes local files. If libcurl +(http://curl.haxx.se/) or libwww (http://www.w3.org/Library) is available, the WFDB library can also read files from any accessible World Wide Web (HTTP) or FTP server. (Writing files to a remote WWW or FTP server may be supported in the future.) -If you do not wish to allow access to remote files, or if libwww is not -available, simply define the symbol WFDB_NETFILES as 0 when compiling the -WFDB library. If the symbol WFDB_NETFILES is zero, wfdblib.h defines +If you do not wish to allow access to remote files, or if neither libcurl nor +libwww is available, simply define the symbol WFDB_NETFILES as 0 when compiling +the WFDB library. If the symbol WFDB_NETFILES is zero, wfdblib.h defines wfdb_fread as fread, wfdb_fwrite as fwrite, etc.; thus in this case, the I/O is performed using the standard C I/O functions, and the function definitions in the next section are not compiled. This behavior exactly @@ -979,7 +978,7 @@ All access to local files is handled by passing the 'fp' member of the WFDB_FILE object to the appropriate standard C I/O function. Access to remote files via http or ftp is handled by passing the 'netfp' member of the WFDB_FILE -object to the appropriate libwww function(s). +object to the appropriate libcurl or libwww function(s). In order to read remote files, the WFDB environment variable should include one or more components that specify http:// or ftp:// URL prefixes. These @@ -1000,13 +999,14 @@ static int nf_open_files = 0; /* number of open netfiles */ static long page_size = NF_PAGE_SIZE; /* bytes per range request (0: disable range requests) */ -static int www_done_init = FALSE; /* TRUE once libwww is initialized */ +static int www_done_init = FALSE; /* TRUE once libcurl or libwww is + initialized */ #if WFDB_NETFILES_LIBCURL static CURL *curl_ua = NULL; /* Construct the User-Agent string to be sent with HTTP requests. */ -static char *curl_get_ua_string() +static char *curl_get_ua_string(void) { char *libcurl_ver; static char *s = NULL; @@ -1064,7 +1064,7 @@ #define chunk_putb HTChunk_putb #endif -void wfdb_wwwquit() +void wfdb_wwwquit(void) { if (www_done_init) { #if WFDB_NETFILES_LIBCURL @@ -1081,7 +1081,7 @@ } } -static void www_init() +static void www_init(void) { if (!www_done_init) { #if WFDB_NETFILES_LIBCURL @@ -1127,8 +1127,8 @@ /* HTHost_setMaxPipelinedRequests(1); */ HTEventInit(); /* added 19 July 2001 -- necessary for use with WINSOCK, seems to be harmless otherwise */ - atexit(wfdb_wwwquit); #endif + atexit(wfdb_wwwquit); www_done_init = TRUE; } } @@ -1452,13 +1452,13 @@ argument (normally an http:// or ftp:// url). If page_size is nonzero and the file can be read in segments (this will be true for files served by http servers that support range requests, and possibly for other types of files - if libwww support is available), nf_new reads the first page_size bytes (or - fewer, if the file is shorter than page_size). Otherwise, nf_new attempts - to read the entire file into memory. If there is insufficient memory, if - the file contains no data, or if the file does not exist (the most common - of these three cases), nf_new returns a NULL pointer; otherwise, it - allocates, fills in, and returns a pointer to a netfile structure that can - be used by nf_fread, etc., to obtain the contents of the file. + if NETFILES support is available), nf_new reads the first page_size bytes + (or fewer, if the file is shorter than page_size). Otherwise, nf_new + attempts to read the entire file into memory. If there is insufficient + memory, if the file contains no data, or if the file does not exist (the + most common of these three cases), nf_new returns a NULL pointer; otherwise, + it allocates, fills in, and returns a pointer to a netfile structure that + can be used by nf_fread, etc., to obtain the contents of the file. It would be useful to be able to copy a file that cannot be read in segments to a local file, but this operation is not currently implemented. The way @@ -1728,32 +1728,28 @@ now just before wfdb_fprintf, which refers to it. There is no completely portable way to make a forward reference to a static (local) function. */ -void wfdb_clearerr(wp) -WFDB_FILE *wp; +void wfdb_clearerr(WFDB_FILE *wp) { if (wp->type == WFDB_NET) return (nf_clearerr(wp->netfp)); return (clearerr(wp->fp)); } -int wfdb_feof(wp) -WFDB_FILE *wp; +int wfdb_feof(WFDB_FILE *wp) { if (wp->type == WFDB_NET) return (nf_feof(wp->netfp)); return (feof(wp->fp)); } -int wfdb_ferror(wp) -WFDB_FILE *wp; +int wfdb_ferror(WFDB_FILE *wp) { if (wp->type == WFDB_NET) return (nf_ferror(wp->netfp)); return (ferror(wp->fp)); } -int wfdb_fflush(wp) -WFDB_FILE *wp; +int wfdb_fflush(WFDB_FILE *wp) { if (wp == NULL) { /* flush all WFDB_FILEs */ nf_fflush(NULL); @@ -1765,48 +1761,35 @@ return (fflush(wp->fp)); } -char* wfdb_fgets(s, size, wp) -char *s; -int size; -WFDB_FILE *wp; +char* wfdb_fgets(char *s, int size, WFDB_FILE *wp) { if (wp->type == WFDB_NET) return (nf_fgets(s, size, wp->netfp)); return (fgets(s, size, wp->fp)); } -size_t wfdb_fread(ptr, size, nmemb, wp) -void *ptr; -size_t size, nmemb; -WFDB_FILE *wp; +size_t wfdb_fread(void *ptr, size_t size, size_t nmemb, WFDB_FILE *wp) { if (wp->type == WFDB_NET) return (nf_fread(ptr, size, nmemb, wp->netfp)); return (fread(ptr, size, nmemb, wp->fp)); } -int wfdb_fseek(wp, offset, whence) -WFDB_FILE *wp; -long offset; -int whence; +int wfdb_fseek(WFDB_FILE *wp, long int offset, int whence) { if (wp->type == WFDB_NET) return (nf_fseek(wp->netfp, offset, whence)); return(fseek(wp->fp, offset, whence)); } -long wfdb_ftell(wp) -WFDB_FILE *wp; +long wfdb_ftell(WFDB_FILE *wp) { if (wp->type == WFDB_NET) return (nf_ftell(wp->netfp)); return (ftell(wp->fp)); } -size_t wfdb_fwrite(ptr, size, nmemb, wp) -void *ptr; -size_t size, nmemb; -WFDB_FILE *wp; +size_t wfdb_fwrite(void *ptr, size_t size, size_t nmemb, WFDB_FILE *wp) { if (wp->type == WFDB_NET) return (nf_fwrite(ptr, size, nmemb, wp->netfp)); @@ -1820,9 +1803,7 @@ return (getc(wp->fp)); } -int wfdb_putc(c, wp) -int c; -WFDB_FILE *wp; +int wfdb_putc(int c, WFDB_FILE *wp) { if (wp->type == WFDB_NET) return (nf_putc(c, wp->netfp)); @@ -1845,9 +1826,7 @@ return (status); } -WFDB_FILE *wfdb_fopen(fname, mode) -char *fname; -const char *mode; +WFDB_FILE *wfdb_fopen(char *fname, const char *mode) { char *p = fname; WFDB_FILE *wp = (WFDB_FILE *)malloc(sizeof(WFDB_FILE)); @@ -1904,8 +1883,7 @@ /* Miscellaneous OS-specific functions. */ #ifdef NOSTRTOK -char *strtok(p, sep) -char *p, *sep; +char *strtok(char *p, char *sep) { char *psep; static char *s; diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/Makefile.top wfdb-10.4.0/Makefile.top --- wfdb-10.3.17/Makefile.top 2001-02-28 13:18:10.000000000 -0500 +++ wfdb-10.4.0/Makefile.top 2005-12-02 10:20:51.000000000 -0500 @@ -1,10 +1,10 @@ # file: Makefile G. Moody 5 September 1990 -# Last revised: 28 February 2001 Version 10.1.6 +# Last revised: 2 December 2005 Version 10.3.18 # UNIX 'make' description file for the WFDB software package # # ----------------------------------------------------------------------------- # WFDB software for creating & using annotated waveform (time series) databases -# Copyright (C) 2001 George B. Moody +# Copyright (C) 1990-2005 George B. Moody # # These programs are free software; you can redistribute them and/or modify # them under the terms of the GNU General Public License as published by the @@ -37,4 +37,5 @@ # appropriate for your system. To compile the package, just type `make' (from # within this directory). To install the package, type `make install'. To # create source archives, type `make tarballs'; or to make a binary archive, -# type `make bin-tarball'. Making archives requires PGP, gzip, and GNU tar). +# type `make bin-tarball'. (Making archives requires PGP, gzip, and GNU tar). +# _____________________________________________________________________________ diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/Makefile.tpl wfdb-10.4.0/Makefile.tpl --- wfdb-10.3.17/Makefile.tpl 2005-08-04 22:04:57.000000000 -0400 +++ wfdb-10.4.0/Makefile.tpl 2006-02-24 23:22:49.000000000 -0500 @@ -1,5 +1,5 @@ # file: Makefile.tpl G. Moody 24 May 2000 -# Last revised: 4 August 2005 +# Last revised: 24 February 2006 # This section of the Makefile should not need to be changed. # 'make' or 'make all': compile the WFDB applications without installing them @@ -12,17 +12,19 @@ cd app; $(MAKE) install cd convert; $(MAKE) install cd data; $(MAKE) install + cd fortran; $(MAKE) install cd psd; $(MAKE) install -( cd wave; $(MAKE) install ) cd waverc; $(MAKE) install test -d doc && ( cd doc; $(MAKE) install ) uninstall: config.cache - cd lib; $(MAKE) uninstall cd app; $(MAKE) uninstall cd convert; $(MAKE) uninstall - cd psd; $(MAKE) uninstall cd data; $(MAKE) uninstall + cd fortran; $(MAKE) uninstall + cd lib; $(MAKE) uninstall + cd psd; $(MAKE) uninstall cd wave; $(MAKE) uninstall cd waverc; $(MAKE) uninstall test -d doc && ( cd doc; $(MAKE) uninstall ) diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/MANIFEST wfdb-10.4.0/MANIFEST --- wfdb-10.3.17/MANIFEST 2005-06-13 04:09:19.000000000 -0400 +++ wfdb-10.4.0/MANIFEST 2006-03-02 12:42:04.000000000 -0500 @@ -342,15 +342,6 @@ doc/wpg/ doc/wpg/info/ doc/wpg/info/README.info -doc/wpg/info/wpg -doc/wpg/info/wpg-1 -doc/wpg/info/wpg-2 -doc/wpg/info/wpg-3 -doc/wpg/info/wpg-4 -doc/wpg/info/wpg-5 -doc/wpg/info/wpg-6 -doc/wpg/info/wpg-7 -doc/wpg/info/wpg-8 doc/wpg-src/ doc/wpg-src/ctotexi.c doc/wpg-src/dir.top diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/NEWS wfdb-10.4.0/NEWS --- wfdb-10.3.17/NEWS 2005-08-20 15:51:38.000000000 -0400 +++ wfdb-10.4.0/NEWS 2006-03-02 18:02:42.000000000 -0500 @@ -1,3 +1,72 @@ +10.4.0: + Version 10.4.0 and later versions of the WFDB library are intended to + be compiled using ANSI/ISO C (and C++) compilers only; previous + versions also supported the use of traditional (K&R) C compilers. The + most obvious change resulting from this decision is in the use of + prototypes in function declarations, an innovation of ANSI C that + permits better error-checking by compilers. The ANSI/ISO C standard is + now more than 15 years old, and it has been over 10 years since a C + compiler that does not support function prototypes was used for + development of the WFDB library. Code in wfdbio.c that provides + limited support for compilers that do not provide an ANSI/ISO C library + has been retained for now, and wfdb.h still includes a set of K&R C + function declarations; both of these features are deprecated, however, + and may be removed in future versions of the WFDB library. Users who + still need to use a K&R C compiler to compile the library itself may + find 'unprotoize' (included in the GNU gcc distribution) to be helpful. + + The WFDB Fortran wrappers (fortran/wfdbf.c) have been revised for + compatibility with gcc 4.x (which no longer supports -fwritable-strings + as a way to convert between C and Fortran strings in place), and + for compatibility with the new (experimental) Fortran 9x compiler, + gfortran, which replaces g77 in gcc 4.x. The revised wrappers remain + compatible with g77 and with the even older f2c translator. + + The symbol WFDB_GVPAD is newly defined in <wfdb/wfdb.h>. It may be + added to WFDB_HIGHRES or WFDB_LOWRES and given as input to setgvmode(). + The effect of doing so is that missing samples, and samples recognized + as invalid, are replaced by getframe (getvec) with the most recently + read valid values rather than by the special value WFDB_INVALID_SAMPLE. + This behavior allows applications such as digital filters to remain + ignorant of missing data without significant performance penalties. + + The mapping of lowest expressible sample values to WFDB_INVALID_SAMPLE + performed by getframe (in lib/signal.c) did not work properly for + signal formats 80 and 160 (in which samples are recorded as unsigned + integers); this has now been corrected. + + The WFDB function 'sample()' now checks that its signal number input + is valid, and returns WFDB_INVALID_SAMPLE if not. + + WFDB applications nst and xform have been revised so that they + correctly handle input that may contain invalid samples. Programs + revised to use WFDB_GVPAD mode are fir, mfilt, sigamp, sqrs, sqrs125, + wabp, and wqrs; all of these now also accept a '-H' option to read + multifrequency records in high-resolution mode. + + Peter Domitrovich contributed an integration routine to memse to + calculate power in bands of interest for HRV analysis. + + Example 7 in the WFDB Programmer's Guide now works properly. The + previous version always began processing the input at sample 0, + regardless of start time specified in its argument list. + + The WFDB Applications Guide now documents the format of variable- + layout records (in header.5). + + WAVE now handles the case of running on an X server that does not + implement backing store more reliably. The code that was introduced + in 10.3.16 did not behave properly with some X servers and window + managers; the latest version avoids this behavior. + + An installation bug caused WAVE not to read its default X11 resource + file from the standard location in some cases. The most visible + effect was that the signal window background would appear grey + rather than white. This bug has been fixed. + + Hardware recommendations for WAVE have been updated in the WAVE + User's Guide. + 10.3.17: The WFDB library now supports reading variable-layout records (multi-segment records in which the number, arrangement, gains, diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/psd/memse.c wfdb-10.4.0/psd/memse.c --- wfdb-10.3.17/psd/memse.c 2005-06-10 09:52:39.000000000 -0400 +++ wfdb-10.4.0/psd/memse.c 2006-02-26 22:44:45.000000000 -0500 @@ -1,9 +1,9 @@ /* file: memse.c G. Moody 6 February 1992 - Last revised: 10 June 2005 + Last revised: 26 February 2006 ------------------------------------------------------------------------------- memse: Estimate power spectrum using maximum entropy (all poles) method -Copyright (C) 1992-2005 George B. Moody +Copyright (C) 1992-2006 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 @@ -29,6 +29,10 @@ This version agrees with 'fft' output (amplitude spectrum with total power equal to the variance); thanks to Joe Mietus. + +The function 'integ' (to compute total power over a band), and the code using +'integ' to summarize power in several bands of interest for HRV analysis, was +contributed by Peter P. Domitrovich. */ #include <stdio.h> @@ -46,30 +50,46 @@ # define strchr index #endif -#define PI M_PI /* pi to machine precision, defined in math.h */ +#define PI M_PI /* pi to machine precision, defined in math.h */ #ifdef i386 #define strcasecmp strcmp #endif -double wsum; +double wsum = 0.0; + +double (*window)(int j, long n); +double win_bartlett(int j, long n); +double win_blackman(int j, long n); +double win_blackman_harris(int j, long n); +double win_hamming(int j, long n); +double win_hanning(int j, long n); +double win_parzen(int j, long n); +double win_square(int j, long n); +double win_welch(int j, long n); +char *prog_name(char *p); +int detrend(double *ordinates, long n_ordinates); +void error(char *error_message); +void help(void); +int memcof(double *data, long n, long m, double *pm, double *cof); +double evlmem(double f, double *cof, long m, double pm); +long input(void); +double integ(double *cof, long poles, double pm, double lowfreq, + double highfreq, double tolerance); /* See Oppenheim & Schafer, Digital Signal Processing, p. 241 (1st ed.) */ -double win_bartlett(j, n) -int j, n; +double win_bartlett(int j, long n) { - double a = 2.0/(n-1), w; - + double a = 2.0/(n-1), w = 0.0; if ((w = j*a) > 1.0) w = 2.0 - w; wsum += w; return (w); } /* See Oppenheim & Schafer, Digital Signal Processing, p. 242 (1st ed.) */ -double win_blackman(j, n) -int j, n; +double win_blackman(int j, long n) { - double a = 2.0*PI/(n-1), w; + double a = 2.0*PI/(n-1), w = 0.0; w = 0.42 - 0.5*cos(a*j) + 0.08*cos(2*a*j); wsum += w; @@ -78,10 +98,9 @@ /* See Harris, F.J., "On the use of windows for harmonic analysis with the discrete Fourier transform", Proc. IEEE, Jan. 1978 */ -double win_blackman_harris(j, n) -int j, n; +double win_blackman_harris(int j, long n) { - double a = 2.0*PI/(n-1), w; + double a = 2.0*PI/(n-1), w = 0.0; w = 0.35875 - 0.48829*cos(a*j) + 0.14128*cos(2*a*j) - 0.01168*cos(3*a*j); wsum += w; @@ -89,10 +108,9 @@ } /* See Oppenheim & Schafer, Digital Signal Processing, p. 242 (1st ed.) */ -double win_hamming(j, n) -int j, n; +double win_hamming(int j, long n) { - double a = 2.0*PI/(n-1), w; + double a = 2.0*PI/(n-1), w = 0.0; w = 0.54 - 0.46*cos(a*j); wsum += w; @@ -101,10 +119,9 @@ /* See Oppenheim & Schafer, Digital Signal Processing, p. 242 (1st ed.) The second edition of Numerical Recipes calls this the "Hann" window. */ -double win_hanning(j, n) -int j, n; +double win_hanning(int j, long n) { - double a = 2.0*PI/(n-1), w; + double a = 2.0*PI/(n-1), w = 0.0; w = 0.5 - 0.5*cos(a*j); wsum += w; @@ -113,10 +130,9 @@ /* See Press, Flannery, Teukolsky, & Vetterling, Numerical Recipes in C, p. 442 (1st ed.) */ -double win_parzen(j, n) -int j, n; +double win_parzen(int j, long n) { - double a = (n-1)/2.0, w; + double a = (n-1)/2.0, w = 0.0; if ((w = (j-a)/(a+1)) > 0.0) w = 1 - w; else w = 1 + w; @@ -125,19 +141,18 @@ } /* See any of the above references. */ -double win_square(j, n) -int j, n; +double win_square(int j, long n) { - wsum += 1.0; + if (j < n) /* to quiet the compiler */ + wsum += 1.0; return (1.0); } /* See Press, Flannery, Teukolsky, & Vetterling, Numerical Recipes in C, p. 442 (1st ed.) or p. 554 (2nd ed.) */ -double win_welch(j, n) -int j, n; +double win_welch(int j, long n) { - double a = (n-1)/2.0, w; + double a = (n-1)/2.0, w = 0.0; w = (j-a)/(a+1); w = 1 - w*w; @@ -145,41 +160,62 @@ return (w); } -char *pname; - -FILE *ifile; -float *data, *wk1, *wk2; +char *pname = NULL; +FILE *ifile = NULL; +double *data = NULL, *wk1 = NULL, *wk2 = NULL; long nmax = 512L; /* Initial buffer size (must be a power of 2). Note that input() will increase this value as necessary by repeated doubling, depending on the length of the input series. */ -float *wkm; -int fflag; -unsigned int len; -unsigned int nout; -unsigned int poles; -int wflag; -int zflag; -double freq, (*window)(); - -main(argc, argv) -int argc; -char *argv[]; -{ - int i, pflag = 0; - char *prog_name(); - double df; - float pm, *cof, evlmem(); - FILE *fp; - long input(); - void detrend(), error(), help(), memcof(); +double pm = 0.0; +double *cof = NULL; +double *wkm = NULL; +int fflag = 0; +long len = 0; +long nout = 0; +long poles = 0; +int wflag = 0; +int zflag = 0; +double freq = 0.0; + +void band_power(double f0, double f1) +{ + double f; + static int first_band = 1; + + if (f0 < 0.0) f0 = 0.0; + if (f1 < 0.0) f1 = 0.0; + if (f0 > f1) { f = f0; f0 = f1; f1 = f; } + if (f0 == f1) return; + if (first_band) { + printf("\nModel order = %ld\n", poles); + printf(" Band (Hz)\t\t Power\n"); + first_band = 0; + } + printf("%lf - %lf\t%lf\n", f0, f1, + 2 * integ(cof, poles, pm, f0, f1, 0.0000001)); +} + +int main(int argc, char **argv) +{ + int i = 0, pflag = 0, sflag = 0, fi, fi0 = -1, fi1 = -1; + double df = 0.0; + double f = 0.0, f0, f1, p = 0.0; pname = prog_name(argv[0]); for (i = 1; i < argc; i++) { if (*argv[i] == '-') switch (*(argv[i]+1)) { + case 'b': /* print power in specified bands */ + if (++i > argc-1 || *argv[i] == '-') + error("at least two frequencies must follow -b"); + fi0 = i; + while (++i < argc && *argv[i] != '-') + ; + fi1 = i--; + break; case 'f': /* print frequencies */ if (++i >= argc) - error("sampling frequency must follow -f"); + error("sampling frequency must follow -f"); freq = atof(argv[i]); fflag = 1; break; @@ -195,20 +231,23 @@ break; case 'n': /* print n equally-spaced output values */ if (++i >= argc) - error("output length must follow -n"); + error("output length must follow -n"); nout = atoi(argv[i]); break; case 'o': /* specify the model order (number of poles) */ if (++i >= argc) - error("order (number of poles) must follow -o"); + error("order (number of poles) must follow -o"); poles = atoi(argv[i]); break; case 'P': /* print power spectrum (squared magnitudes) */ pflag = 1; break; + case 's': /* summarize power in HRV bands of interest */ + sflag = 1; + break; case 'w': /* apply windowing function to input */ if (++i >= argc) - error("window type must follow -w"); + error("window type must follow -w"); if (strcasecmp(argv[i], "Bartlett") == 0) window = win_bartlett; else if (strcasecmp(argv[i], "Blackman") == 0) @@ -217,13 +256,14 @@ window = win_blackman_harris; else if (strcasecmp(argv[i], "Hamming") == 0) window = win_hamming; - else if (strcasecmp(argv[i], "Hanning") == 0) + else if (strcasecmp(argv[i], "Hanning") == 0 || + strcasecmp(argv[i], "Hann") == 0) window = win_hanning; else if (strcasecmp(argv[i], "Parzen") == 0) window = win_parzen; - else if (strcasecmp(argv[i], "Square") == 0 || + else if (strcasecmp(argv[i], "Dirichlet") == 0 || strcasecmp(argv[i], "Rectangular") == 0 || - strcasecmp(argv[i], "Dirichlet") == 0) + strcasecmp(argv[i], "Square") == 0) window = win_square; else if (strcasecmp(argv[i], "Welch") == 0) window = win_welch; @@ -261,32 +301,29 @@ } /* Read the input series. */ - len = input(); + len = input( ); /* Check the model order. */ if (poles > len) poles = len; if ((double)poles*poles > len) - fprintf(stderr, - "%s: the model order (number of poles) may be too high\n", - pname); + fprintf(stderr, "%s: the model order (number of poles) may be too high\n", pname); /* Set the model order to a reasonable value if it is unspecified. */ if (poles == 0) { poles = (int)(sqrt((double)len) + 0.5); - fprintf(stderr, - "%s: using a model order of %d\n", pname, poles); + fprintf(stderr, "%s: using a model order of %ld\n", pname, poles); } /* Allocate arrays for coefficients. */ - if ((cof = (float *)malloc((unsigned)poles*sizeof(float))) == NULL || - (wkm = (float *)malloc((unsigned)poles*sizeof(float))) == NULL) { + if (((cof = (double *)malloc((unsigned)poles*sizeof(double))) == NULL) || + ((wkm = (double *)malloc((unsigned)poles*sizeof(double))) == NULL)) { fprintf(stderr, "%s: insufficient memory\n", pname); exit(1); } /* Zero-mean, detrend, and/or window the input series as required. */ if (zflag) { - double rmean, rsum = 0; + double rmean = 0, rsum = 0; for (i = 0; i < len; i++) rsum += data[i]; @@ -299,26 +336,53 @@ if (wflag) for (i = 0; i < len; i++) data[i] *= (*window)(i, len); - + /* Calculate coefficients for MEM spectral estimation. */ memcof(data, len, poles, &pm, cof); /* If the number of output points was not specified, choose the largest - power of 2 less than len, plus 1 (so that the number of output points - matches that produced by an FFT). */ + power of 2 less than len, plus 1 (so that the number of output points + matches that produced by an FFT). */ if (nout == 0) { while (nmax >= len) - nmax /= 2;; + nmax /= 2; nout = nmax + 1; } /* Print outputs. */ - for (i = 0, df = 0.5/(nout-1); i < nout; i++) { - if (fflag) printf("%g\t", i*df*freq); - if (pflag) - printf("%g\n", evlmem(i*df, cof, poles, pm)/(nout-1)); - else - printf("%g\n", sqrt(evlmem(i*df, cof, poles, pm)/(nout-1))); + if (nout > 1) + for (i = 0, df = 0.5/((double)(nout-1)); i < nout; i++) { + f = i*df*freq; + p = evlmem(i*df, cof, poles, pm)/((double)(nout-1)); + if (fflag) printf("%lf\t", i*df*freq); + if (pflag) + printf("%lf\n", + evlmem(i*df, cof, poles, pm)/((double)(nout-1))); + else + printf("%lf\n", + sqrt(evlmem(i*df, cof, poles, pm)/((double)(nout-1)))); + } + else { + free(cof); + free(data); + free(wk1); + free(wk2); + free(wkm); + error("no output produced"); + } + + if (sflag) { + band_power(0.0, 0.5); + band_power(0.0, 0.0033); + band_power(0.0033, 0.04); + band_power(0.04, 0.15); + band_power(0.15, 0.4); + band_power(0.4, 0.5); + } + for (fi = fi0; fi < fi1-1; ) { + f0 = atof(argv[fi++]); + f1 = atof(argv[fi++]); + band_power(f0, f1); } free(cof); @@ -327,17 +391,15 @@ free(wk2); free(wkm); - exit(0); + return 0; } /* Calculate coefficients for MEM spectral estimation. See Numerical Recipes, pp. 447-451. */ -void memcof(data, n, m, pm, cof) -float *data, *pm, *cof; -unsigned int n, m; +int memcof(double *data, long n, long m, double *pm, double *cof) { - int i, j, k; - float denom, num, p = 0.0; + int i = 0, j = 0, k = 0; + double denom = 0.0, num = 0.0, p = 0.0; for (j = 0; j < n; j++) p += data[j]*data[j]; @@ -367,19 +429,17 @@ } } } + return 0; } /* Evaluate power spectral estimate at f (0 <= f < = 0.5, where 1 is the sampling frequency), given MEM coefficients in cof[0 ... m-1] and pm (see Numerical Recipes, pp. 451-452). */ -float evlmem(f, cof, m, pm) -double f; -float *cof, pm; -unsigned int m; +double evlmem(double f, double *cof, long m, double pm) { - int i; - float sumr = 1.0, sumi = 0.0; - double wr = 1.0, wi = 0.0, wpr, wpi, wt, theta; + int i = 0; + double sumr = 1.0, sumi = 0.0; + double wr = 1.0, wi = 0.0, wpr = 0.0, wpi = 0.0, wt = 0.0, theta = 0.0; theta = 2.0*PI*f; wpr = cos(theta); @@ -393,14 +453,12 @@ } -/* This function detrends (subtracts a least-squares fitted line from) a - a sequence of n uniformily spaced ordinates supplied in c. */ -void detrend(c, n) -float *c; -int n; +/* This function detrends (subtracts a least-squares fitted line from) + a sequence of n uniformly spaced ordinates supplied in c. */ +int detrend(double *c, long n) { - int i; - double a, b = 0.0, tsqsum = 0.0, ysum = 0.0, t; + int i = 0; + double a = 0.0, b = 0.0, tsqsum = 0.0, ysum = 0.0, t = 0.0; for (i = 0; i < n; i++) ysum += c[i]; @@ -417,10 +475,10 @@ fprintf(stderr, "%s: (warning) possibly significant trend in input series\n", pname); + return 0; } -char *prog_name(s) -char *s; +char *prog_name(char *s) { char *p = s + strlen(s); @@ -439,8 +497,7 @@ return (p+1); } -void error(s) -char *s; +void error(char *s) { fprintf(stderr, "%s: %s\n", pname, s); exit(1); @@ -450,6 +507,8 @@ "usage: %s [ OPTIONS ...] INPUT-FILE\n", " where INPUT-FILE is the name of a text file containing a time series", " (use `-' to read the standard input), and OPTIONS may be any of:", +" -b LF HF Print the power in the frequency band defined by LF and HF. More", +" than one band may be specified following a single -b option.", " -f FREQ Show the center frequency for each bin in the first column. The", " FREQ argument specifies the input sampling frequency; the center", " frequencies are given in the same units.", @@ -459,6 +518,7 @@ " -o P Specify the model order (number of poles); default: P = the square", " root of the number of input samples.", " -P Generate a power spectrum (print squared magnitudes).", +" -s Print a summary of power in bands of interest for HRV analysis.", " -w WINDOW", " Apply the specified WINDOW to the input data. WINDOW may be one", " of: `Bartlett', `Blackman', `Blackman-Harris', `Hamming',", @@ -468,13 +528,21 @@ NULL }; -void help() +void help(void) { int i; (void)fprintf(stderr, help_strings[0], pname); - for (i = 1; help_strings[i] != NULL; i++) + for (i = 1; help_strings[i] != NULL; i++) { (void)fprintf(stderr, "%s\n", help_strings[i]); + if (i % 23 == 0) { + char b[5]; + (void)fprintf(stderr, "--More--"); + (void)fgets(b, 5, stdin); + (void)fprintf(stderr, "\033[A\033[2K"); /* erase "--More--"; + assumes ANSI terminal */ + } + } } /* Read input data, allocating and filling x[] and y[]. The return value is @@ -484,48 +552,48 @@ the available memory (assuming that a long int is large enough to address any memory location). */ -long input() +long input( ) { - unsigned long npts = 0L; + long npts = 0L; - if ((data = (float *)malloc(nmax * sizeof(float))) == NULL || - (wk1 = (float *)malloc(64 * nmax * sizeof(float))) == NULL || - (wk2 = (float *)malloc(64 * nmax * sizeof(float))) == NULL) { + if (((data = (double *)malloc(nmax * sizeof(double))) == NULL) || + ((wk1 = (double *)malloc(64 * nmax * sizeof(double))) == NULL) || + ((wk2 = (double *)malloc(64 * nmax * sizeof(double))) == NULL)) { if (data) (void)free(data); if (wk1) (void)free(wk1); fclose(ifile); - error("insufficient memory"); + error("insufficient memory"); } - while (fscanf(ifile, "%f", &data[npts]) == 1) { + while (fscanf(ifile, "%lf", &data[npts]) == 1) { if (++npts >= nmax) { /* double the size of the input buffers */ - unsigned long nmaxt = nmax << 1; - float *datat, *w1t, *w2t; + long nmaxt = nmax << 1; + double *datat = NULL, *w1t = NULL, *w2t = NULL; - if (nmaxt * sizeof(float) < nmax) { + if ((long)(nmaxt * sizeof(double)) < nmax) { fprintf(stderr, - "%s: insufficient memory, truncating input at row %d\n", - pname, npts); + "%s: insufficient memory, truncating input at row %ld\n", + pname, npts); break; } - if ((datat = (float *)realloc(data,nmaxt*sizeof(float))) == NULL) { + if ((datat = (double *)realloc(data,nmaxt*sizeof(double)))==NULL) { fprintf(stderr, - "%s: insufficient memory, truncating input at row %d\n", - pname, npts); + "%s: insufficient memory, truncating input at row %ld\n", + pname, npts); break; } data = datat; - if ((w1t = (float *)realloc(wk1,64*nmaxt*sizeof(float))) == NULL){ + if ((w1t = (double *)realloc(wk1,64*nmaxt*sizeof(double)))==NULL) { fprintf(stderr, - "%s: insufficient memory, truncating input at row %d\n", - pname, npts); + "%s: insufficient memory, truncating input at row %ld\n", + pname, npts); break; } wk1 = w1t; - if ((w2t = (float *)realloc(wk2,64*nmaxt*sizeof(float))) == NULL){ + if ((w2t = (double *)realloc(wk2,64*nmaxt*sizeof(double)))==NULL) { fprintf(stderr, - "%s: insufficient memory, truncating input at row %d\n", - pname, npts); + "%s: insufficient memory, truncating input at row %ld\n", + pname, npts); break; } wk2 = w2t; @@ -537,3 +605,91 @@ if (npts < 1) error("no data read"); return (npts); } + +/* Function 'integ' was contributed by Peter J. Domitrovich, who translated it + from a FORTRAN version by an unknown author from a book written in Chinese. + This code is designed to integrate functions with sharp peaks. */ +double integ(double *aa, long m, double ee, double a, double b, double epsilon) +{ + double f[3][31], fm[3][31], e[3][31], krtn[31]; + double sum = 0.0, t = 1.0, absa = 1.0, est = 1.0, f1 = 0.0, fa = 0.0, + fb = 0.0, fp = 0.0, x = a, da = b - a, dx = 0.0, sx = 0.0, fm1 = 0.0, + e1 = 0.0, s = 0.0; + long l = 0, k = 0; + + fa = evlmem(a, aa, m, ee); + fb = evlmem(b, aa, m, ee); + fp = 4.0 * evlmem(0.5 * (a + b), aa, m, ee); + while (1) { + k = 1; + l++; + t *= 1.7; + dx = da / 3.0; + sx = dx / 6.0; + fm1 = 4.0 * evlmem(x + 0.5 * dx, aa, m, ee); + f1 = evlmem(x + dx, aa, m, ee); + fm[1][l] = fp; + f[1][l] = evlmem(x + 2.0 * dx, aa, m, ee); + fm[2][l] = 4.0 * evlmem (x + 2.5 * dx, aa, m, ee); + f[2][l] = fb; + e1 = sx * (fa + fm1 + f1); + e[1][l] = sx * (f1 + fp + f[1][l]); + e[2][l] = sx * (f[1][l] + fm[2][l] + fb); + s = e1 + e[1][l] + e[2][l]; + absa = absa - fabs(est) + fabs(e1) + fabs(e[1][l]) + fabs(e[2][l]); + if (fabs (est - 1.0) < 1.0e-06) { + est = e1; + fp = fm1; + fb = f1; + da = dx; + krtn[l] = k; + continue; + } + if (t * fabs (est - s) <= epsilon * absa) { + sum += s; + do { + l--; + t /= 1.7; + k = krtn[l]; + dx *= 3.0; + if (k == 3 && l - 1 <= 0) + return sum; + } while (k == 3 && l - 1 > 0); + est = e[k][l]; + fp = fm[k][l]; + fa = fb; + fb = f[k][l]; + k++; + x += da; + da = dx; + krtn[l] = k; + continue; + } + if (l < 30) { + est = e1; + fp = fm1; + fb = f1; + da = dx; + krtn[l] = k; + continue; + } + sum += 5.0; + do { + l--; + t /= 1.7; + k = krtn[l]; + dx *= 3.0; + if (k == 3 && l - 1 <= 0) + return sum; + } while (k == 3 && l - 1 > 0); + est = e[k][l]; + fp = fm[k][l]; + fa = fb; + fb = f[k][l]; + k++; + x += da; + da = dx; + krtn[l] = k; + } +} + diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/wave/Makefile.tpl wfdb-10.4.0/wave/Makefile.tpl --- wfdb-10.3.17/wave/Makefile.tpl 2005-06-14 16:20:57.000000000 -0400 +++ wfdb-10.4.0/wave/Makefile.tpl 2005-12-02 11:47:10.000000000 -0500 @@ -1,5 +1,5 @@ # file: Makefile.tpl G. Moody 31 May 2000 -# Last revised: 31 May 2005 +# Last revised: 2 December 2005 # Change the settings below as appropriate for your setup. # Choose directories in which to install WAVE and its ancillary files by @@ -51,6 +51,7 @@ -cp wavemenu.def $(MENUDIR) && \ $(SETPERMISSIONS) $(MENUDIR)/wavemenu.def -cp Wave.res $(RESDIR)/Wave && $(SETPERMISSIONS) $(RESDIR)/Wave + $(MAKE) clean uninstall: ../uninstall.sh $(BINDIR) wave diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/wave/sig.c wfdb-10.4.0/wave/sig.c --- wfdb-10.3.17/wave/sig.c 2005-08-05 13:32:51.000000000 -0400 +++ wfdb-10.4.0/wave/sig.c 2006-02-06 07:29:55.000000000 -0500 @@ -1,10 +1,10 @@ -/* file: sig.c G. Moody 27 April 1990 - Last revised: 10 June 2005 +/* file: sig.c G. Moody 27 April 1990 + Last revised: 6 February 2006 Signal display functions for WAVE ------------------------------------------------------------------------------- WAVE: Waveform analyzer, viewer, and editor -Copyright (C) 1990-2005 George B. Moody +Copyright (C) 1990-2006 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 @@ -383,21 +383,25 @@ double w; /* weight assigned to ymean in y-offset calculation */ tp = lp->vlist[c]; - ymean = 0; ymax = -32768; ymin = 32767; - for (j = n = 0, n = 1; j < i; j++) { + + /* Find the first valid sample in the trace, if any. */ + for (j = 0; j < i && tp[j].y == WFDB_INVALID_SAMPLE; j++) + ; + ymean = ymax = ymin = (j < i) ? tp[j].y : 0; + for (n = 1; j < i; j++) { if ((y = tp[j].y) != WFDB_INVALID_SAMPLE) { - if (y > ymax) ymax = y; + if (y > ymax) ymax = y; else if (y < ymin) ymin = y; ymean += y; n++; } } + ymean /= n; ymid = (ymax + ymin)/2; - if (n > 0) ymean /= n; /* Since ymin <= ymid <= ymax, the next lines imply 0 <= w <= 1 */ if (ymid > ymean) /* in this case, ymax must be > ymean */ w = (ymid - ymean)/(ymax - ymean); - else if (ymid < ymean) /* in this case, ymin must be < ymin */ + else if (ymid < ymean) /* in this case, ymin must be < ymean */ w = (ymean - ymid)/(ymean - ymin); else w = 1.0; dy = -(ymid + ((double)ymean-ymid)*w); diff -Naur --exclude Makefile --exclude info wfdb-10.3.17/wave/xvwave.c wfdb-10.4.0/wave/xvwave.c --- wfdb-10.3.17/wave/xvwave.c 2005-08-05 13:34:10.000000000 -0400 +++ wfdb-10.4.0/wave/xvwave.c 2005-08-30 12:22:52.000000000 -0400 @@ -1,5 +1,5 @@ /* file: xvwave.c G. Moody 27 April 1990 - Last revised: 5 August 2005 + Last revised: 30 August 2005 XView support functions for WAVE ------------------------------------------------------------------------------- @@ -133,11 +133,7 @@ int width; int height; { - XEvent nextev; - if (in_xv_main_loop) { - XPeekEvent((Display *)xv_get(canvas, XV_DISPLAY), &nextev); - if (nextev.type == ConfigureNotify) do_resize(canvas, width, height); - } + if (in_xv_main_loop) do_resize(canvas, width, height); } /* This function handles interpretation of XView options and initialization of @@ -704,17 +700,6 @@ WIN_DYNAMIC_VISUAL, use_overlays, 0); -#if 0 - /* Get the actual dimensions of the created canvas. Use the resize - procedure to adjust the width if necessary and to set the scales. */ - canvas_height = (int)xv_get(canvas, CANVAS_HEIGHT); - canvas_width = (int)xv_get(canvas, CANVAS_WIDTH); - do_resize(canvas, canvas_width, canvas_height); - - window_fit(canvas); - window_fit(frame); -#endif - /* Get the display and paint window of the canvas, and the X ID (drawable) of its paint window. */ display = (Display *)xv_get(canvas, XV_DISPLAY);