some improvements to digital play mode:
-use AUMODE_PLAY_ALL, from Sergey Svishchev -- this might cause stuttering if the write to audio can't keep up, but it avoids pauses if the audio buffer drains out on stop/resume -The timeout for the raw SCSI command to read audio data was too small, causing complete failure for me. -Since the itimer can't do faster than HZ, a too small buffer doesn't work. Try to calculate a sensible buffer size. -While it makes sense to deliver data a bit faster than necessary, it should be not that much that the blocking in the signal handler hurts interactive response. Allow for 50ms. -Comment out a sched_yield() in the signal handler - this doesn't look right. This is far from being perfect, but it makes digital mode usable for me. And for Jeremy C. Reed, the author of PR bin/38493.
This commit is contained in:
parent
657e141577
commit
1f6364ac89
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: cdplay.c,v 1.38 2007/01/24 10:36:33 abs Exp $ */
|
||||
/* $NetBSD: cdplay.c,v 1.39 2008/07/16 17:26:25 drochner Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1999, 2000, 2001 Andrew Doran.
|
||||
@ -40,7 +40,7 @@
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: cdplay.c,v 1.38 2007/01/24 10:36:33 abs Exp $");
|
||||
__RCSID("$NetBSD: cdplay.c,v 1.39 2008/07/16 17:26:25 drochner Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
@ -483,7 +483,7 @@ run(int cmd, const char *arg)
|
||||
|
||||
case CMD_DIGITAL:
|
||||
if (digital == 0) {
|
||||
int fpw;
|
||||
int fpw, intv_usecs, hz_usecs;
|
||||
|
||||
fpw = atoi(arg);
|
||||
if (fpw > 0)
|
||||
@ -491,6 +491,23 @@ run(int cmd, const char *arg)
|
||||
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");
|
||||
@ -500,9 +517,10 @@ run(int cmd, const char *arg)
|
||||
warn("Cannot open audio device");
|
||||
return (1);
|
||||
}
|
||||
itv_timer.it_interval.tv_sec = itv_timer.it_value.tv_sec = da.fpw / 75;
|
||||
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 =
|
||||
(da.fpw * 6666) % 1000000;
|
||||
intv_usecs % 1000000;
|
||||
rv = setitimer(ITIMER_REAL, &itv_timer, NULL);
|
||||
if (rv == 0) {
|
||||
digital = 1;
|
||||
@ -837,7 +855,9 @@ sig_timer(int sig)
|
||||
}
|
||||
if (shuffle)
|
||||
skip(0, 0);
|
||||
#if 0
|
||||
sched_yield();
|
||||
#endif
|
||||
setitimer(ITIMER_REAL, &itv_timer, NULL);
|
||||
}
|
||||
|
||||
@ -932,7 +952,8 @@ print_status(const char *arg)
|
||||
else
|
||||
printf("shuffle play:\t%s\n", (shuffle != 0) ? "on" : "off");
|
||||
if (digital)
|
||||
printf("digital xfer:\tto %s (%d frames per wakeup, %ld.%03lds period)\n",
|
||||
printf("digital xfer:\tto %s "
|
||||
"(%d frames per wakeup, %ld.%06lds period)\n",
|
||||
da.auname, da.fpw, itv_timer.it_interval.tv_sec,
|
||||
itv_timer.it_interval.tv_usec);
|
||||
else
|
||||
@ -1346,7 +1367,7 @@ openaudio()
|
||||
da.afd = -1;
|
||||
return (0);
|
||||
}
|
||||
ai.mode = AUMODE_PLAY;
|
||||
ai.mode = AUMODE_PLAY_ALL;
|
||||
ai.play.sample_rate = 44100;
|
||||
ai.play.channels = 2;
|
||||
ai.play.precision = 16;
|
||||
@ -1387,7 +1408,7 @@ readaudio(afd, lba, blocks, data)
|
||||
sc.datalen = CDDA_SIZE * blocks;
|
||||
sc.senselen = sizeof(sc.sense);
|
||||
sc.flags = SCCMD_READ;
|
||||
sc.timeout = da.fpw * 15;
|
||||
sc.timeout = 10000; /* 10s */
|
||||
rc = ioctl(afd, SCIOCCOMMAND, &sc);
|
||||
if (rc < 0 || sc.retsts != SCCMD_OK) {
|
||||
if (da.read_errors < 10) {
|
||||
|
Loading…
Reference in New Issue
Block a user