Module Name:    src
Committed By:   christos
Date:           Sat Nov 26 23:20:41 UTC 2011

Modified Files:
        src/usr.bin/cdplay: cdplay.1 cdplay.c

Log Message:
If the ioctl to play tracks returned EINVAL, switch to digital mode and
try again.
XXX: Should we do this for the other ioctls? Should we default to digital mode?
Definitely the error message is completely unfriendly and should be fixed.


To generate a diff of this commit:
cvs rdiff -u -r1.22 -r1.23 src/usr.bin/cdplay/cdplay.1
cvs rdiff -u -r1.43 -r1.44 src/usr.bin/cdplay/cdplay.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/cdplay/cdplay.1
diff -u src/usr.bin/cdplay/cdplay.1:1.22 src/usr.bin/cdplay/cdplay.1:1.23
--- src/usr.bin/cdplay/cdplay.1:1.22	Mon Apr 23 07:47:55 2007
+++ src/usr.bin/cdplay/cdplay.1	Sat Nov 26 18:20:41 2011
@@ -1,4 +1,4 @@
-.\"	$NetBSD: cdplay.1,v 1.22 2007/04/23 11:47:55 tron Exp $
+.\"	$NetBSD: cdplay.1,v 1.23 2011/11/26 23:20:41 christos Exp $
 .\"
 .\" Copyright (c) 1999, 2000 Andrew Doran.
 .\" All rights reserved.
@@ -26,7 +26,7 @@
 .\"
 .\" from FreeBSD: cdcontrol.1,v 1.16.2.2 1999/01/31 15:36:01 billf Exp
 .\"
-.Dd April 23, 2007
+.Dd November 26, 2011
 .Dt CDPLAY 1
 .Os
 .Sh NAME
@@ -183,6 +183,8 @@ stereo samples).
 Audio data are read and written in groups of
 .Ar n
 frames (5 by default, or 1/15 seconds).
+.It Cm analog
+Switch from digital back to analog mode.
 .It Cm help
 Print the list of available commands.
 .It Cm reset

Index: src/usr.bin/cdplay/cdplay.c
diff -u src/usr.bin/cdplay/cdplay.c:1.43 src/usr.bin/cdplay/cdplay.c:1.44
--- src/usr.bin/cdplay/cdplay.c:1.43	Mon Aug 29 10:00:54 2011
+++ src/usr.bin/cdplay/cdplay.c	Sat Nov 26 18:20:41 2011
@@ -1,4 +1,4 @@
-/* 	$NetBSD: cdplay.c,v 1.43 2011/08/29 14:00:54 joerg Exp $	*/
+/* 	$NetBSD: cdplay.c,v 1.44 2011/11/26 23:20:41 christos Exp $	*/
 
 /*
  * Copyright (c) 1999, 2000, 2001 Andrew Doran.
@@ -40,7 +40,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: cdplay.c,v 1.43 2011/08/29 14:00:54 joerg Exp $");
+__RCSID("$NetBSD: cdplay.c,v 1.44 2011/11/26 23:20:41 christos Exp $");
 #endif /* not lint */
 
 #include <sys/types.h>
@@ -69,6 +69,7 @@ __RCSID("$NetBSD: cdplay.c,v 1.43 2011/0
 #include <util.h>
 
 enum cmd {
+	CMD_ANALOG,
 	CMD_CLOSE,
 	CMD_DIGITAL,
 	CMD_EJECT,
@@ -96,18 +97,19 @@ static struct cmdtab {
 	unsigned int	min;
 	const char	*args;
 } const cmdtab[] = {
-	{ CMD_HELP,	"?",	   1, 0 },
+	{ CMD_ANALOG,	"analog",  1, NULL },
 	{ CMD_CLOSE,	"close",   1, NULL },
 	{ CMD_DIGITAL,	"digital", 1, "fpw" },
 	{ CMD_EJECT,	"eject",   1, NULL },
+	{ CMD_HELP,	"?",	   1, 0 },
 	{ CMD_HELP,	"help",    1, NULL },
 	{ CMD_INFO,	"info",    1, NULL },
 	{ CMD_NEXT,	"next",    1, NULL },
 	{ CMD_PAUSE,	"pause",   2, NULL },
+	{ CMD_PLAY,	"play",    1, "[#block [len]]" },
 	{ CMD_PLAY,	"play",    1, "min1:sec1[.fram1] [min2:sec2[.fram2]]" },
-	{ CMD_PLAY,	"play",    1, "track1[.index1] [track2[.index2]]" },
 	{ CMD_PLAY,	"play",    1, "tr1 m1:s1[.f1] [[tr2] [m2:s2[.f2]]]" },
-	{ CMD_PLAY,	"play",    1, "[#block [len]]" },
+	{ CMD_PLAY,	"play",    1, "track1[.index1] [track2[.index2]]" },
 	{ CMD_PREV,	"prev",    2, NULL },
 	{ CMD_QUIT,	"quit",    1, NULL },
 	{ CMD_RESET,	"reset",   4, NULL },
@@ -179,6 +181,8 @@ static const char	*prompt(void);
 static int	readaudio(int, int, int, u_char *);
 static int	read_toc_entrys(int);
 static int	run(int, const char *);
+static int	start_analog(void);
+static int	start_digital(const char *);
 static int	setvol(int, int);
 static void	sig_timer(int);
 static int	skip(int, int);
@@ -345,6 +349,75 @@ help(void)
 }
 
 static int
+start_digital(const char *arg)
+{
+
+	int fpw, intv_usecs, hz_usecs, rv;
+
+	fpw = atoi(arg);
+	if (fpw > 0)
+		da.fpw = fpw;
+	else
+		da.fpw = 5;
+	da.read_errors = 0;
+
+	/* real rate: 75 frames per second */
+	intv_usecs = 13333 * da.fpw;
+	/*
+	 * interrupt earlier for safety, by a value which
+	 * doesn't hurt interactice response if we block
+	 * in the signal handler
+	 */
+	intv_usecs -= 50000;
+	hz_usecs = 1000000 / sysconf(_SC_CLK_TCK);
+	if (intv_usecs < hz_usecs) {
+		/* can't have a shorter interval, increase
+		   buffer size to compensate */
+		da.fpw += (hz_usecs - intv_usecs) / 13333;
+		intv_usecs = hz_usecs;
+	}
+
+	da.aubuf = malloc(da.fpw * CDDA_SIZE);
+	if (da.aubuf == NULL) {
+		warn("Not enough memory for audio buffers");
+		return (1);
+	}
+	if (da.afd == -1 && !openaudio()) {
+		warn("Cannot open audio device");
+		return (1);
+	}
+	itv_timer.it_interval.tv_sec = itv_timer.it_value.tv_sec =
+		intv_usecs / 1000000;
+	itv_timer.it_interval.tv_usec = itv_timer.it_value.tv_usec =
+		intv_usecs % 1000000;
+	rv = setitimer(ITIMER_REAL, &itv_timer, NULL);
+	if (rv == 0) {
+		digital = 1;
+	} else
+		warn("setitimer in CMD_DIGITAL");
+	msf = 0;
+	tbvalid = 0;
+	return rv;
+}
+
+static int
+start_analog(void)
+{
+	int rv;
+	if (shuffle == 1)
+		itv_timer.it_interval.tv_sec = itv_timer.it_value.tv_sec = 1;
+	else
+		itv_timer.it_interval.tv_sec = itv_timer.it_value.tv_sec = 0;
+	itv_timer.it_interval.tv_usec = itv_timer.it_value.tv_usec = 0;
+	digital = 0;
+	rv = setitimer(ITIMER_REAL, &itv_timer, NULL);
+	free(da.audata);
+	close(da.afd);
+	da.afd = -1;
+	return rv;
+}
+
+static int
 run(int cmd, const char *arg)
 {
 	int l, r, rv;
@@ -481,65 +554,22 @@ run(int cmd, const char *arg)
 		break;
 
 	case CMD_DIGITAL:
-		if (digital == 0) {
-			int fpw, intv_usecs, hz_usecs;
-
-			fpw = atoi(arg);
-			if (fpw > 0)
-				da.fpw = fpw;
-			else
-				da.fpw = 5;
-			da.read_errors = 0;
-
-			/* real rate: 75 frames per second */
-			intv_usecs = 13333 * da.fpw;
-			/*
-			 * interrupt earlier for safety, by a value which
-			 * doesn't hurt interactice response if we block
-			 * in the signal handler
-			 */
-			intv_usecs -= 50000;
-			hz_usecs = 1000000 / sysconf(_SC_CLK_TCK);
-			if (intv_usecs < hz_usecs) {
-				/* can't have a shorter interval, increase
-				   buffer size to compensate */
-				da.fpw += (hz_usecs - intv_usecs) / 13333;
-				intv_usecs = hz_usecs;
-			}
+		if (digital == 0)
+			rv = start_digital(arg);
+		else {
+			warnx("Already in digital mode");
+			rv = 1;
+		}
+		break;
 
-			da.aubuf = malloc(da.fpw * CDDA_SIZE);
-			if (da.aubuf == NULL) {
-				warn("Not enough memory for audio buffers");
-				return (1);
-			}
-			if (da.afd == -1 && !openaudio()) {
-				warn("Cannot open audio device");
-				return (1);
-			}
-			itv_timer.it_interval.tv_sec = itv_timer.it_value.tv_sec =
-				intv_usecs / 1000000;
-			itv_timer.it_interval.tv_usec = itv_timer.it_value.tv_usec =
-				intv_usecs % 1000000;
-			rv = setitimer(ITIMER_REAL, &itv_timer, NULL);
-			if (rv == 0) {
-				digital = 1;
-			} else
-				warnx("setitimer in CMD_DIGITAL");
-			msf = 0;
-			tbvalid = 0;
-		} else {
-			if (shuffle == 1)
-				itv_timer.it_interval.tv_sec = itv_timer.it_value.tv_sec = 1;
-			else
-				itv_timer.it_interval.tv_sec = itv_timer.it_value.tv_sec = 0;
-			itv_timer.it_interval.tv_usec = itv_timer.it_value.tv_usec = 0;
-			digital = 0;
-			rv = setitimer(ITIMER_REAL, &itv_timer, NULL);
-			free(da.audata);
-			close(da.afd);
-			da.afd = -1;
+	case CMD_ANALOG:
+		if (digital == 1)
+			rv = start_analog();
+		else {
+			warnx("Already in analog mode");
+			rv = 1;
 		}
-		return (0);
+		break;
 
 	case CMD_SKIP:
 		if (!interactive)
@@ -1100,8 +1130,13 @@ play_track(int tstart, int istart, int t
 	t.end_track = tend;
 	t.end_index = iend;
 
-	if ((rv = ioctl(fd, CDIOCPLAYTRACKS, &t)) < 0)
+	if ((rv = ioctl(fd, CDIOCPLAYTRACKS, &t)) < 0) {
+		int oerrno = errno;
+		if (errno == EINVAL && start_digital("5") == 0)
+			return play_track(tstart, istart, tend, iend);
+		errno = oerrno;
 		warn("ioctl(CDIOCPLAYTRACKS)");
+	}
 	return (rv);
 }
 

Reply via email to