Module Name:    src
Committed By:   mlelstv
Date:           Sat Apr 15 12:39:44 UTC 2023

Modified Files:
        src/usr.bin/audio/common: auconv.h wav.c
        src/usr.bin/audio/play: play.c
        src/usr.bin/audio/record: record.c

Log Message:
Add support for recording 24bit wav files.


To generate a diff of this commit:
cvs rdiff -u -r1.5 -r1.6 src/usr.bin/audio/common/auconv.h
cvs rdiff -u -r1.15 -r1.16 src/usr.bin/audio/common/wav.c
cvs rdiff -u -r1.61 -r1.62 src/usr.bin/audio/play/play.c
cvs rdiff -u -r1.56 -r1.57 src/usr.bin/audio/record/record.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.bin/audio/common/auconv.h
diff -u src/usr.bin/audio/common/auconv.h:1.5 src/usr.bin/audio/common/auconv.h:1.6
--- src/usr.bin/audio/common/auconv.h:1.5	Mon Apr 28 20:24:12 2008
+++ src/usr.bin/audio/common/auconv.h	Sat Apr 15 12:39:44 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: auconv.h,v 1.5 2008/04/28 20:24:12 martin Exp $	*/
+/*	$NetBSD: auconv.h,v 1.6 2023/04/15 12:39:44 mlelstv Exp $	*/
 
 /*-
  * Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -78,6 +78,24 @@ change_sign16_be(u_char *p, int cc)
 }
 
 static inline void
+change_sign24_le(u_char *p, int cc)
+{
+	while ((cc -= 3) >= 0) {
+		p[2] ^= 0x80;
+		p += 3;
+	}
+}
+
+static inline void
+change_sign24_be(u_char *p, int cc)
+{
+	while ((cc -= 3) >= 0) {
+		p[0] ^= 0x80;
+		p += 3;
+	}
+}
+
+static inline void
 change_sign32_le(u_char *p, int cc)
 {
 	while ((cc -= 4) >= 0) {
@@ -163,6 +181,44 @@ change_sign16_swap_bytes_be(u_char *p, i
 }
 
 static inline void
+swap_bytes_change_sign24_le(u_char *p, int cc)
+{
+	u_char t;
+
+	while ((cc -= 3) >= 0) {
+		t = p[2];
+		p[2] = p[0] ^ 0x80;
+		p[0] = t;
+		p += 3;
+	}
+}
+
+static inline void
+swap_bytes_change_sign24_be(u_char *p, int cc)
+{
+	u_char t;
+
+	while ((cc -= 3) >= 0) {
+		t = p[0];
+		p[0] = p[2] ^ 0x80;
+		p[2] = t;
+		p += 3;
+	}
+}
+
+static inline void
+change_sign24_swap_bytes_le(u_char *p, int cc)
+{
+	swap_bytes_change_sign24_be(p, cc);
+}
+
+static inline void
+change_sign24_swap_bytes_be(u_char *p, int cc)
+{
+	swap_bytes_change_sign24_le(p, cc);
+}
+
+static inline void
 swap_bytes_change_sign32_le(u_char *p, int cc)
 {
 	u_char t;

Index: src/usr.bin/audio/common/wav.c
diff -u src/usr.bin/audio/common/wav.c:1.15 src/usr.bin/audio/common/wav.c:1.16
--- src/usr.bin/audio/common/wav.c:1.15	Sat Nov  9 12:46:44 2019
+++ src/usr.bin/audio/common/wav.c	Sat Apr 15 12:39:44 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: wav.c,v 1.15 2019/11/09 12:46:44 mrg Exp $	*/
+/*	$NetBSD: wav.c,v 1.16 2023/04/15 12:39:44 mlelstv Exp $	*/
 
 /*
  * Copyright (c) 2002, 2009, 2013, 2015, 2019 Matthew R. Green
@@ -33,7 +33,7 @@
 #include <sys/cdefs.h>
 
 #ifndef lint
-__RCSID("$NetBSD: wav.c,v 1.15 2019/11/09 12:46:44 mrg Exp $");
+__RCSID("$NetBSD: wav.c,v 1.16 2023/04/15 12:39:44 mlelstv Exp $");
 #endif
 
 
@@ -287,6 +287,8 @@ wav_prepare_header(struct track_info *ti
 		break;
 	case 16:
 		break;
+	case 24:
+		break;
 	case 32:
 		break;
 	default:

Index: src/usr.bin/audio/play/play.c
diff -u src/usr.bin/audio/play/play.c:1.61 src/usr.bin/audio/play/play.c:1.62
--- src/usr.bin/audio/play/play.c:1.61	Sun May 15 02:16:06 2022
+++ src/usr.bin/audio/play/play.c	Sat Apr 15 12:39:44 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: play.c,v 1.61 2022/05/15 02:16:06 mrg Exp $	*/
+/*	$NetBSD: play.c,v 1.62 2023/04/15 12:39:44 mlelstv Exp $	*/
 
 /*
  * Copyright (c) 1999, 2000, 2001, 2002, 2010, 2015, 2019, 2021 Matthew R. Green
@@ -28,7 +28,7 @@
 #include <sys/cdefs.h>
 
 #ifndef lint
-__RCSID("$NetBSD: play.c,v 1.61 2022/05/15 02:16:06 mrg Exp $");
+__RCSID("$NetBSD: play.c,v 1.62 2023/04/15 12:39:44 mlelstv Exp $");
 #endif
 
 #include <sys/param.h>
@@ -65,6 +65,7 @@ static int	volume;
 static int	balance;
 static int	port;
 static int	fflag;
+static int	lflag;
 static int	qflag;
 int	verbose;
 static int	sample_rate;
@@ -87,7 +88,7 @@ main(int argc, char *argv[])
 	const char *defdevice = _PATH_SOUND;
 	const char *device = NULL;
 
-	while ((ch = getopt(argc, argv, "b:B:C:c:d:e:fhip:P:qs:Vv:")) != -1) {
+	while ((ch = getopt(argc, argv, "b:B:C:c:d:e:fhilp:P:qs:Vv:")) != -1) {
 		switch (ch) {
 		case 'b':
 			decode_int(optarg, &balance);
@@ -118,6 +119,9 @@ main(int argc, char *argv[])
 		case 'i':
 			iflag++;
 			break;
+		case 'l':
+			lflag++;
+			break;
 		case 'q':
 			qflag++;
 			break;
@@ -297,6 +301,57 @@ audio_write(int fd, void *buf, size_t le
 	return write(fd, convert_buffer, len);
 }
 
+/*
+ * print audio output offset
+ */
+static void
+print_offset(off_t written, int ratelimit)
+{
+	static time_t last;
+	time_t now;
+	static off_t base = 0;
+	static off_t played = 0;
+	off_t bps;
+	audio_offset_t aoff;
+	u_int blocksize;
+
+	if (!lflag)
+		return;
+
+	if (ioctl(audiofd, AUDIO_GETOOFFS, &aoff))
+		return;
+
+	bps = info.play.sample_rate
+	          * info.play.channels
+	          * info.play.precision / NBBY;
+	blocksize = info.blocksize > 0 ? info.blocksize : 1;
+
+	/* Check if aoff.samples overflowed */
+	if (aoff.samples < played) {
+		base += UINT_MAX;
+		base += 1;
+	}
+
+	/* Overflow base + number of samples in completed blocks + offset in currently played block */
+	played = base + aoff.samples + (aoff.offset % blocksize);
+
+	/* Print only every second */
+	if (ratelimit) {
+		time(&now);
+		if (now == last)
+			return;
+		last = now;
+	}
+
+	if (bps > 0) {
+		printf("%jdms\n", (written - played) * 1000 / bps);
+	} else {
+		/* unknown rate, report bytes */
+		printf("%jd\n", written - played);
+	}
+	fflush(stdout);
+}
+
 static void
 play(char *file)
 {
@@ -305,7 +360,7 @@ play(char *file)
 	void *addr, *oaddr;
 	off_t	filesize;
 	size_t	sizet_filesize;
-	off_t datasize = 0;
+	off_t datasize = 0, written = 0;
 	ssize_t	hdrlen;
 	int fd;
 	int nw;
@@ -369,6 +424,7 @@ play(char *file)
 	}
 
 	while ((uint64_t)datasize > bufsize) {
+		print_offset(written, 0);
 		nw = audio_write(audiofd, addr, bufsize, conv);
 		if (nw == -1)
 			err(1, "write failed");
@@ -376,13 +432,17 @@ play(char *file)
 			errx(1, "write failed");
 		addr = (char *)addr + bufsize;
 		datasize -= bufsize;
+		written += nw;
 	}
+	print_offset(written, 0);
 	nw = audio_write(audiofd, addr, datasize, conv);
 	if (nw == -1)
 		err(1, "final write failed");
 	if ((off_t)nw != datasize)
 		errx(1, "final write failed");
+	written += nw;
 
+	print_offset(written, 0);
 	if (ioctl(audiofd, AUDIO_DRAIN) < 0 && !qflag)
 		warn("audio drain ioctl failed");
 	if (munmap(oaddr, sizet_filesize) < 0)
@@ -401,7 +461,7 @@ play_fd(const char *file, int fd)
 	char    *buffer = malloc(bufsize);
 	ssize_t hdrlen;
 	int     nr, nw;
-	off_t	datasize = 0;
+	off_t	datasize = 0, written = 0;
 	off_t	dataout = 0;
 
 	if (buffer == NULL)
@@ -430,6 +490,8 @@ play_fd(const char *file, int fd)
 		memmove(buffer, buffer + hdrlen, nr - hdrlen);
 		nr -= hdrlen;
 	}
+
+	print_offset(written, 0);
 	while (datasize == 0 || dataout < datasize) {
 		if (datasize != 0 && dataout + nr > datasize)
 			nr = datasize - dataout;
@@ -444,10 +506,13 @@ play_fd(const char *file, int fd)
 			goto read_error;
 		if (nr == 0)
 			break;
+		print_offset(written, 1);
+		written += nw;
 	}
 	/* something to think about: no message given for dataout < datasize */
 	if (ioctl(audiofd, AUDIO_DRAIN) < 0 && !qflag)
 		warn("audio drain ioctl failed");
+	print_offset(written, 0);
 	return;
 read_error:
 	err(1, "read of standard input failed");
@@ -573,6 +638,8 @@ set_audio_mode:
 
 	if (ioctl(fd, AUDIO_SETINFO, &info) < 0)
 		err(1, "failed to set audio info");
+	if (ioctl(fd, AUDIO_GETINFO, &info) < 0)
+		err(1, "failed to re-get audio info");
 
 	return (hdr_len);
 }
@@ -581,7 +648,7 @@ static void
 usage(void)
 {
 
-	fprintf(stderr, "Usage: %s [-hiqV] [options] files\n", getprogname());
+	fprintf(stderr, "Usage: %s [-hilqV] [options] files\n", getprogname());
 	fprintf(stderr, "Options:\n\t"
 	    "-B buffer size\n\t"
 	    "-b balance (0-63)\n\t"

Index: src/usr.bin/audio/record/record.c
diff -u src/usr.bin/audio/record/record.c:1.56 src/usr.bin/audio/record/record.c:1.57
--- src/usr.bin/audio/record/record.c:1.56	Sun Jan  9 06:33:13 2022
+++ src/usr.bin/audio/record/record.c	Sat Apr 15 12:39:44 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: record.c,v 1.56 2022/01/09 06:33:13 mlelstv Exp $	*/
+/*	$NetBSD: record.c,v 1.57 2023/04/15 12:39:44 mlelstv Exp $	*/
 
 /*
  * Copyright (c) 1999, 2002, 2003, 2005, 2010 Matthew R. Green
@@ -32,7 +32,7 @@
 #include <sys/cdefs.h>
 
 #ifndef lint
-__RCSID("$NetBSD: record.c,v 1.56 2022/01/09 06:33:13 mlelstv Exp $");
+__RCSID("$NetBSD: record.c,v 1.57 2023/04/15 12:39:44 mlelstv Exp $");
 #endif
 
 
@@ -312,14 +312,22 @@ main(int argc, char *argv[])
 			s = "change sign (big-endian, 16 bit)";
 		else if (conv_func == change_sign16_le)
 			s = "change sign (little-endian, 16 bit)";
+		else if (conv_func == change_sign24_be)
+			s = "change sign (big-endian, 24 bit)";
+		else if (conv_func == change_sign24_le)
+			s = "change sign (little-endian, 24 bit)";
 		else if (conv_func == change_sign32_be)
 			s = "change sign (big-endian, 32 bit)";
 		else if (conv_func == change_sign32_le)
 			s = "change sign (little-endian, 32 bit)";
 		else if (conv_func == change_sign16_swap_bytes_be)
 			s = "change sign & swap bytes (big-endian, 16 bit)";
-		else if (conv_func == change_sign16_swap_bytes_le)
+		else if (conv_func == change_sign24_swap_bytes_le)
 			s = "change sign & swap bytes (little-endian, 16 bit)";
+		else if (conv_func == change_sign16_swap_bytes_be)
+			s = "change sign & swap bytes (big-endian, 24 bit)";
+		else if (conv_func == change_sign24_swap_bytes_le)
+			s = "change sign & swap bytes (little-endian, 24 bit)";
 		else if (conv_func == change_sign32_swap_bytes_be)
 			s = "change sign (big-endian, 32 bit)";
 		else if (conv_func == change_sign32_swap_bytes_le)

Reply via email to