[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This program illustrates the use of sample
to obtain random
access to signals, a technique that is particularly
useful for implementing digital filters. The first argument is the
record name, the second and third arguments are the start time and the
duration of the segment to be filtered, and the rest of the arguments
are finite-impulse-response (FIR) filter coefficients. For example, if
this program were compiled into an executable program called
`filter', it might be used by
filter 100 5:0 20 .2 .2 .2 .2 .2 |
1 #include <stdio.h> 2 #include <wfdb/wfdb.h> 3 4 main(argc, argv) 5 int argc; 6 char *argv[]; 7 { 8 double *c, one = 1.0, vv, atof(); 9 int i, j, nc = argc - 4, nsig; 10 WFDB_Time nsamp, t, t0, t1; 11 static WFDB_Sample *v; 12 static WFDB_Siginfo *s; 13 14 if (argc < 4) { 15 fprintf(stderr, 16 "usage: %s record start duration [ coefficients ... ]\n", 17 argv[0]); 18 exit(1); 19 } 20 if (nc < 1) { 21 nc = 1; c = &one; 22 } 23 else if ((c = (double *)calloc(nc, sizeof(double))) == NULL) { 24 fprintf(stderr, "%s: too many coefficients\n", argv[0]); 25 exit(2); 26 } 27 for (i = 0; i < nc; i++) 28 c[i] = atof(argv[i+4]); 29 if ((nsig = isigopen(argv[1], NULL, 0)) < 1) 30 exit(3); 31 s = (WFDB_Siginfo *)malloc(nsig * sizeof(WFDB_Siginfo)); 32 v = (WFDB_Sample *)malloc(nsig * sizeof(WFDB_Sample)); 33 if (s == NULL || v == NULL) { 34 fprintf(stderr, "insufficient memory\n"); 35 exit(4); 36 } 37 if (isigopen(argv[1], s, nsig) != nsig) 38 exit(5); 39 t0 = strtim(argv[2]); 40 if (t0 < (WFDB_Time)0) t0 = -t0; 41 (void)sample(0, t0); 42 if (!sample_valid()) { 43 fprintf(stderr, "%s: inappropriate value for start time\n", 44 argv[0]); 45 exit(6); 46 } 47 if ((nsamp = strtim(argv[3])) < 1) { 48 fprintf(stderr, "%s: inappropriate value for duration\n", 49 argv[0]); 50 exit(7); 51 } 52 t1 = t0 + nsamp; 53 if (osigopen("16l", s, nsig) != nsig) 54 exit(8); 55 56 for (t = t0; t < t1 && sample_valid(); t++) { 57 for (j = 0; j < nsig; j++) { 58 for (i = 0, vv = 0.; i < nc; i++) 59 if (c[i] != 0.) vv += c[i]*sample(j, t+i); 60 v[j] = (WFDB_Sample)vv; 61 } 62 if (putvec(v) < 0) break; 63 } 64 65 (void)newheader("out"); 66 wfdbquit(); 67 exit(0); 68 } |
(See http://www.physionet.org/physiotools/wfdb/examples/example7.c for a copy of this program.)
Notes:
double
format and stored in the coefficient
vector.
argv[1]
, and the start time is argv[2]
;
if the record can't be opened, the program exits. See the previous example
for details on how isigopen
is used. If the user provides an absolute
start time
(see section [ms]timstr),
the negative value returned by strtim
is converted to a sample number
in line 40.
sample
is invoked only for its side effect; if any samples can
be read from the specified record beginning at sample number t0
, then
sample(0, 0L)
returns a valid sample, so that the value returned by
sample_valid
is true (1). If not, the program exits.
strtim
converts it to the appropriate number of
samples, and t1
is set to the calculated end time in line 52.
vv
) is initialized to zero in line 58 before we begin, and is
converted to a 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 t1
,
or we run out of input samples.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |