diff -Naur --exclude Makefile --exclude info wfdb-10.4.15/app/wfdbtime.c wfdb-10.4.16/app/wfdbtime.c
--- wfdb-10.4.15/app/wfdbtime.c	2009-02-16 23:36:19.000000000 -0500
+++ wfdb-10.4.16/app/wfdbtime.c	2009-03-01 16:33:04.000000000 -0500
@@ -27,32 +27,33 @@
 #include <stdio.h>
 #include <wfdb/wfdb.h>
 
-main(argc, argv)
-int argc;
-char **argv;
+main(int argc, char **argv)
 {
-    char sbuf[32];
+    char *record = NULL, sbuf[32];
     int i;
     WFDB_Time t;
 
-    if (strcmp(argv[1], "-H") == 0) {
-	setgvmode(WFDB_HIGHRES);
-	argc--; argv++;
+    for (i = 1; i < argc; i++) {
+	if (strcmp(argv[i], "-r") == 0) {
+	    if (record) wfdbquit();
+	    setgvmode(WFDB_HIGHRES);
+	    if (++i == argc) break;
+	    record = argv[i];
+	    if (isigopen(record, NULL, 0) < 0) exit(2);
+	}
+	else if (record) {
+	    if ((t = strtim(argv[i])) < 0L) t = -t;
+	    sprintf(sbuf, "s%ld", t);
+	    printf("%15s\t%15s", sbuf, (t == 0L) ? "0:00.000" : mstimstr(t));
+	    printf("\t%15s\n", mstimstr(-t));
+	}
     }
-    if (strcmp(argv[1], "-r") <= 0 && isigopen(argv[2], NULL, 0) < 0) {
-	fprintf(stderr, "usage: %s [-H] -r RECORD TIME [ TIME ... ]\n",
-		argv[0]);
+    if (record == NULL) {
+	fprintf(stderr, "usage: %s [ -r RECORD [ TIME ] ]\n", argv[0]);
 	fprintf(stderr, " where RECORD is the name of the input record\n");
-	fprintf(stderr, " (use -H for high resolution mode multifrequency"
-		" record)\n");
 	fprintf(stderr, " Each TIME is a time to be converted\n");
 	exit(1);
     }
-    for (i = 3; i < argc; i++) {
-	if ((t = strtim(argv[i])) < 0L) t = -t;
-	sprintf(sbuf, "s%ld", t);
-	printf("%15s\t%15s", sbuf, (t == 0L) ? "0:00.000" : mstimstr(t));
-	printf("\t%15s\n", mstimstr(-t));
-    }
+    wfdbquit();
     exit(0);
 }
diff -Naur --exclude Makefile --exclude info wfdb-10.4.15/app/wrann.c wfdb-10.4.16/app/wrann.c
--- wfdb-10.4.15/app/wrann.c	2008-03-14 13:52:09.000000000 -0400
+++ wfdb-10.4.16/app/wrann.c	2009-02-27 09:45:08.000000000 -0500
@@ -1,9 +1,9 @@
 /* file wrann.c		G. Moody	 6 July 1983
-			Last revised:  14 March 2008
+			Last revised:  27 February 2009
 
 -------------------------------------------------------------------------------
 wrann: Translate an ASCII file in 'rdann' output format to an annotation file
-Copyright (C) 1983-2008 George B. Moody
+Copyright (C) 1983-2009 George B. Moody
 
 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
@@ -103,22 +103,22 @@
     if (annopen(record, &ai, 1) < 0)	/* open annotation file */
 	exit(2);
     while (fgets(line, sizeof(line), stdin) != NULL) {
+	static char a[256];
 	p = line+9;
 	if (line[0] == '[')
 	    while (*p != ']')
 		p++;
 	while (*p != ' ')
 	    p++;
-	(void)sscanf(p+1, "%ld%s%d%d%d", &tm, annstr, &sub, &ch, &nm);
+	*(a+1) = '\0';
+	(void)sscanf(p+1, "%ld%s%d%d%d\t%s", &tm, annstr, &sub, &ch, &nm, a+1);
 	annot.anntyp = strann(annstr);
 	annot.time = tm; annot.subtyp = sub; annot.chan = ch; annot.num = nm;
-	for (p = line+40; *p; p++)
-	    if (*p == '\t') {
-		*p = strlen(p+1) - 1;
-		annot.aux = p;
-		break;
-	    }
-	if (*p == '\0')
+	if (*(a+1)) {
+	    *a = strlen(a+1);
+	    annot.aux = a;
+	}
+	else
 	    annot.aux = NULL;
 	(void)putann(0, &annot);
     }
diff -Naur --exclude Makefile --exclude info wfdb-10.4.15/convert/wfdb2mat.c wfdb-10.4.16/convert/wfdb2mat.c
--- wfdb-10.4.15/convert/wfdb2mat.c	2009-02-26 18:27:21.000000000 -0500
+++ wfdb-10.4.16/convert/wfdb2mat.c	2009-03-01 10:47:38.000000000 -0500
@@ -1,5 +1,5 @@
-/* file: wfdb2mat.c	G. Moody	 26 February 2009
-
+/* file: wfdb2mat.c	G. Moody	26 February 2009
+			Last revised:	  1 March 2009
 -------------------------------------------------------------------------------
 wfdb2mat: Convert (all or part of) a WFDB signal file to Matlab .mat format
 Copyright (C) 2009 George B. Moody
@@ -40,7 +40,9 @@
 files are written in column-major order (i.e., all of column n precedes all of
 column n+1), each vector of samples is written as a column rather than as a
 row, so that the column number in the .mat file equals the sample number in the
-input record.  If this seems odd, transpose your matrix after reading it!
+input record (minus however many samples were skipped at the beginning of the
+record, as specified using the -f option).  If this seems odd, transpose your
+matrix after reading it!
 
 This program writes version 4 MAT-file format output files, as documented in
 http://www.mathworks.com/access/helpdesk/help/pdf_doc/matlab/matfile_format.pdf
@@ -71,14 +73,26 @@
 #include <stdio.h>
 #include <wfdb/wfdb.h>
 
+/* Dynamic memory allocation macros. */
+#define MEMERR(P, N, S) \
+    { wfdb_error("%s: can't allocate (%ld*%ld) bytes for %s\n", \
+		 pname, (size_t)N, (size_t)S, #P);		\
+      exit(1); }
+#define SFREE(P) { if (P) { free (P); P = 0; } }
+#define SUALLOC(P, N, S) { if (!(P = calloc((N), (S)))) MEMERR(P, (N), (S)); }
+#define SALLOC(P, N, S) { SFREE(P); SUALLOC(P, (N), (S)) }
+#define SREALLOC(P, N, S) { if (!(P = realloc(P, (N)*(S)))) MEMERR(P,(N),(S)); }
+#define SSTRCPY(P, Q) { if (Q) { \
+	 SALLOC(P, (size_t)strlen(Q)+1,1); strcpy(P, Q); } }
+
 char *pname;
 
 main(argc, argv)
 int argc;
 char *argv[];
 {
-    char *matname, *orec, *p, *record = NULL, *search = NULL, *prog_name();
-    static int prolog[6];    /* assumes sizeof(int) == 4; if not true, fix! */
+    char *matname, *orec, *p, *q, *record = NULL, *search = NULL, *prog_name();
+    static char prolog[24];
     int highres = 0, i, isiglist, nisig, nosig = 0, pflag = 0, s, *sig = NULL,
         type = 50, vflag = 0;
     WFDB_Frequency freq;
@@ -165,11 +179,8 @@
 	exit(1);
     }
     if ((nisig = isigopen(record, NULL, 0)) <= 0) exit(2);
-    if ((vi = malloc(nisig * sizeof(WFDB_Sample))) == NULL ||
-	(si = malloc(nisig * sizeof(WFDB_Siginfo))) == NULL) {
-	(void)fprintf(stderr, "%s: insufficient memory\n", pname);
-	exit(2);
-    }
+    SUALLOC(si, nisig, sizeof(WFDB_Siginfo));
+    SUALLOC(vi, nisig, sizeof(WFDB_Sample));
     if ((nisig = isigopen(record, si, nisig)) <= 0)
 	exit(2);
     for (i = 0; i < nisig; i++)
@@ -185,12 +196,9 @@
 	to = -to;
 
     if (nosig) {	      /* convert samples only from specified signals */
-	if ((sig = (int *)malloc((unsigned)nosig*sizeof(int))) == NULL ||
-	    (vo = malloc(nosig * sizeof(WFDB_Sample))) == NULL ||
-	    (so = malloc((unsigned)nosig * sizeof(WFDB_Siginfo))) == NULL) {
-	    (void)fprintf(stderr, "%s: insufficient memory\n", pname);
-	    exit(2);
-	}
+	SUALLOC(so, nosig, sizeof(WFDB_Siginfo));
+	SUALLOC(vo, nosig, sizeof(WFDB_Sample));
+	SUALLOC(sig, nosig, sizeof(int));
 	for (i = 0; i < nosig; i++) {
 	    if ((s = findsig(argv[isiglist+i])) < 0) {
 		(void)fprintf(stderr, "%s: can't read signal '%s'\n", pname,
@@ -202,11 +210,9 @@
     }
     else {			/* convert samples from all signals */
 	nosig = nisig;
-	if ((sig = (int *)malloc((unsigned)nosig*sizeof(int))) == NULL ||
-	    (so = malloc((unsigned)nosig * sizeof(WFDB_Siginfo))) == NULL) {
-	    (void)fprintf(stderr, "%s: insufficient memory\n", pname);
-	    exit(2);
-	}
+	SUALLOC(so, nosig, sizeof(WFDB_Siginfo));
+	SUALLOC(vo, nosig, sizeof(WFDB_Sample));
+	SUALLOC(sig, nosig, sizeof(int));
 	for (i = 0; i < nosig; i++)
 	    sig[i] = i;
     }
@@ -237,14 +243,11 @@
 	exit(1);
     }
 
-    /* Generate the names for the output .mat file, and the output record. */
-    if ((matname = (char *)malloc(strlen(record)+5)) == NULL ||
-	(orec = (char *)malloc(strlen(record)+1)) == NULL) {
-	(void)fprintf(stderr, "%s: insufficient memory\n", pname);
-	exit(2);
-    }
+    /* Generate the names for the output .mat file and the output record. */
+    SUALLOC(matname, strlen(record)+6, sizeof(char));
+    sprintf(matname, "%sm.mat", record);
+    SUALLOC(orec, strlen(record)+2, sizeof(char));
     sprintf(orec, "%sm", record);
-    sprintf(matname, "%s.mat", orec);
 
     /* Determine if we can write 8-bit unsigned samples, or if 16 bits are
        needed per sample. */
@@ -254,6 +257,7 @@
 	so[i] = si[sig[i]];
 	so[i].fname = matname;
 	so[i].fmt = (type == 30) ? 16 : 80;
+	if (so[i].units == NULL) SSTRCPY(so[i].units, "mV");
     }
 
     /* Create an empty .mat file. */
@@ -262,36 +266,62 @@
 	exit(1);
     }
     
-    /* Fill in the .mat file's prolog and write it. */
-    prolog[0] = type;		/* format */
-    prolog[1] = nosig;		/* number of rows */
-    prolog[2] = to - from;	/* number of columns */
-    prolog[3] = 0;		/* matrix is real */
-    prolog[4] = 4;		/* strlen("val") + 1 */
-    prolog[5] = ((int)'v') | ((int)'a' << 8) | ((int)'l' << 16); /* "val" */
-    wfdbputprolog((char *)prolog, sizeof(prolog), 0);
+    /* Fill in the .mat file's prolog and write it. (Elements of prolog[]
+       not set explicitly below are always zero.) */
+    prolog[ 0] = type & 0xff;				/* format */
+    prolog[ 1] = (type >> 8) & 0xff;
+    prolog[ 4] = nosig & 0xff;			/* number of rows */
+    prolog[ 5] = (nosig >> 8) & 0xff;
+    prolog[ 6] = (nosig >> 16) & 0xff;
+    prolog[ 7] = (nosig >> 24) & 0xff;
+    prolog[ 8] = (to - from) & 0xff;		/* number of columns */
+    prolog[ 9] = ((to - from) >> 8) & 0xff;
+    prolog[10] = ((to - from) >> 16) & 0xff;
+    prolog[11] = ((to - from) >> 24) & 0xff;
+    prolog[16] = 4;		/* strlen("val") + 1 */
+    sprintf(prolog+20, "val");
+    wfdbputprolog((char *)prolog, 24, 0);
 
     /* Copy the selected data into the .mat file. */
-    for (t = from; from < to && getvec(vi) >= 0; t++) {
+    for (t = from; t < to && getvec(vi) >= 0; t++) {
 	for (i = 0; i < nosig; i++)
 	    vo[i] = vi[sig[i]];
 	if (putvec(vo) != nosig)
 	    break;
     }
 
+    if (t != to)
+	fprintf(stderr, "%s (warning): matrix is missing final %ld columns\n",
+		pname, to - t);
+
     /* Create the new header file. */
     newheader(orec);
-    if (p = malloc(strlen(record)+40)) {
-	sprintf(p, "created using wfdb2mat from record %s", record);
-	putinfo(p);
-	free(p);
+    /* Copy info from the old record, if any */
+    if (p = getinfo(NULL))
+	do {
+	    (void)putinfo(p);
+	} while (p = getinfo((char *)NULL));
+    /* Append additional info summarizing what wfdb2mat has done. */
+    SUALLOC(p, strlen(record)+80, 1);
+    (void)sprintf(p, "Creator: %s", pname);
+    (void)putinfo(p);
+    (void)sprintf(p, "Source: record %s", record);
+    q = mstimstr(-from);
+    while (*q == ' ') q++;
+    if (from != 0 || *q == '[') {
+	strcat(p, "  Start: ");
+	strcat(p, q);
     }
+    (void)putinfo(p);
 
     /* Summarize the contents of the .mat file. */
-    printf("Generated %s, containing matrix 'val'\n", matname);
-    printf(" with %d rows and %d columns\n", nosig, to-from);
+    printf("%s\n", p);
+    printf("val has %d row%s (signal%s) and %d column%s (sample%s/signal)\n",
+	   nosig, nosig == 1 ? "" : "s", nosig == 1 ? "" : "s",
+	   to-from, to == from+1 ? "" : "s", to == from+1 ? "" : "s");
     printf("Duration: %s\n", timstr(to-from));
-    printf("Sampling frequency: %g columns/second\n", sampfreq(NULL));
+    printf("Sampling frequency: %g Hz  Sampling interval: %g sec\n",
+	   freq, 1/freq);
     printf("Row\tSignal\tGain\tBase\tUnits\n");
     for (i = 0; i < nosig; i++)
 	printf("%d\t%s\t%g\t%d\t%s\n", i+1, so[i].desc, so[i].gain,
@@ -299,6 +329,7 @@
     printf("\nTo convert from raw units to the physical units shown\n"
 	   "above, subtract 'base' and divide by 'gain'.\n");
 
+    SFREE(p);
     wfdbquit();
 
     exit(0);	/*NOTREACHED*/
diff -Naur --exclude Makefile --exclude info wfdb-10.4.15/doc/wag-src/wfdbtime.1 wfdb-10.4.16/doc/wag-src/wfdbtime.1
--- wfdb-10.4.15/doc/wag-src/wfdbtime.1	2009-02-18 18:25:33.000000000 -0500
+++ wfdb-10.4.16/doc/wag-src/wfdbtime.1	2009-03-01 17:35:49.000000000 -0500
@@ -1,8 +1,8 @@
-.TH WFDBTIME 1 "18 February 2009" "WFDB 10.4.14" "WFDB Applications Guide"
+.TH WFDBTIME 1 "1 March 2009" "WFDB 10.4.16" "WFDB Applications Guide"
 .SH NAME
 wfdbtime \- convert time to sample number, elapsed, and absolute time
 .SH SYNOPSIS
-\fBwfdbtime\fR [ \fB-H\fR ] \fB-r\fR \fIrecord\fR \fItime\fR [ \fItime\fR ... ]
+\fBwfdbtime\fR \fB-r\fR \fIrecord\fR \fItime\fR [ \fItime\fR ... ]
 .SH DESCRIPTION
 .PP
 Using the specified \fIrecord\fR as a reference for determining the
@@ -17,6 +17,10 @@
 DD/MM/YYYY\fR]).  If the base time for the record is undefined, the
 absolute time cannot be calculated, and in this case the elapsed time
 appears (a second time) instead.
+.PP
+Additional \fB-r\fI record\fR arguments may be given in the same command,
+to reset the sample interval length and base time for any subsequent \fItime\fR
+arguments.
 .SH EXAMPLES
 .PP
 The command
@@ -25,6 +29,7 @@
 .LP
 produces the output
 .IP
+.br
              s0	       0:00.000	[12:40:38.000 20/07/1995]
 .br
          s75000	      10:00.000	[12:50:38.000 20/07/1995]
diff -Naur --exclude Makefile --exclude info wfdb-10.4.15/lib/signal.c wfdb-10.4.16/lib/signal.c
--- wfdb-10.4.15/lib/signal.c	2009-02-26 18:09:34.000000000 -0500
+++ wfdb-10.4.16/lib/signal.c	2009-03-01 15:45:39.000000000 -0500
@@ -3098,7 +3098,7 @@
 	    if (strchr(p, '/')) days = strdat(p) - bdate;
 	    else days = atol(p+1);
 	}
-	t = strtim(string+1) - (WFDB_Time)(btime*f/1000.0);
+	t = strtim(string+1) - (WFDB_Time)(btime*f/1000.0 + 0.5);
 	if (days > 0L) t += (WFDB_Time)(days*24*60*60*f);
 	return (-t);
       default:
diff -Naur --exclude Makefile --exclude info wfdb-10.4.15/lib/wfdb.h wfdb-10.4.16/lib/wfdb.h
--- wfdb-10.4.15/lib/wfdb.h	2009-02-26 22:52:13.000000000 -0500
+++ wfdb-10.4.16/lib/wfdb.h	2009-03-03 07:27:43.000000000 -0500
@@ -33,7 +33,7 @@
 /* WFDB library version. */
 #define WFDB_MAJOR   10
 #define WFDB_MINOR   4
-#define WFDB_RELEASE 15
+#define WFDB_RELEASE 16
 #define WFDB_NETFILES 1	/* if 1, library includes code for HTTP, FTP clients */
 #define WFDB_NETFILES_LIBCURL 1
 
diff -Naur --exclude Makefile --exclude info wfdb-10.4.15/NEWS wfdb-10.4.16/NEWS
--- wfdb-10.4.15/NEWS	2009-02-26 23:06:17.000000000 -0500
+++ wfdb-10.4.16/NEWS	2009-03-03 12:01:38.000000000 -0500
@@ -1,3 +1,13 @@
+10.4.16:
+	WFDB library function strtim() now rounds rather than truncating when
+	the sampling frequency is not an integer.
+
+	WFDB application wrann is now (slightly) less fussy about its input
+	and no longer requires the tab character preceding an aux string to
+	occur in a specific column as did earlier versions.
+
+	Bug fixes in convert/wfdbtomat.
+
 10.4.15:
 	WFDB library function mstimstr() now outputs time to the nearest
 	millisecond, rather than truncating its calculation to the next
