From 44b9771a143d02ea1b04e72f635f1f8260672c07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Schmidt?= Date: Wed, 3 Sep 1997 19:08:05 +0000 Subject: [PATCH] 1) Changed the volume to be a little louder. 2) Added a non_blocking flag to the write routine. 3) Added a 3rd buffer (actually a ring buffer would be better) Submitted by: Jim Lowe --- sys/i386/isa/pcaudio.c | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/sys/i386/isa/pcaudio.c b/sys/i386/isa/pcaudio.c index c371055932a..9773a42c07c 100644 --- a/sys/i386/isa/pcaudio.c +++ b/sys/i386/isa/pcaudio.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id$ + * $Id: pcaudio.c,v 1.34 1997/02/22 09:36:58 peter Exp $ */ #include "pca.h" @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -60,9 +61,9 @@ static struct pca_status { char open; /* device open */ char queries; /* did others try opening */ - unsigned char *buf[2]; /* double buffering */ + unsigned char *buf[3]; /* triple buffering */ unsigned char *buffer; /* current buffer ptr */ - unsigned in_use[2]; /* buffers fill */ + unsigned in_use[3]; /* buffers fill */ unsigned index; /* index in current buffer */ unsigned counter; /* sample counter */ unsigned scale; /* sample counter scale */ @@ -74,10 +75,12 @@ static struct pca_status { unsigned char oldval; /* old timer port value */ char timer_on; /* is playback running */ struct selinfo wsel; /* select status */ + char non_block; /* set non-block on write status */ } pca_status; static char buffer1[BUF_SIZE]; static char buffer2[BUF_SIZE]; +static char buffer3[BUF_SIZE]; static char volume_table[256]; #ifdef DEVFS @@ -133,7 +136,10 @@ pca_volume(int volume) int i, j; for (i=0; i<256; i++) { + j = ((i-128)*volume)/25; +/* XXX j = ((i-128)*volume)/100; +*/ if (j<-128) j = -128; if (j>127) @@ -151,8 +157,9 @@ pca_init(void) pca_status.timer_on = 0; pca_status.buf[0] = (unsigned char *)&buffer1[0]; pca_status.buf[1] = (unsigned char *)&buffer2[0]; + pca_status.buf[2] = (unsigned char *)&buffer3[0]; pca_status.buffer = pca_status.buf[0]; - pca_status.in_use[0] = pca_status.in_use[1] = 0; + pca_status.in_use[0] = pca_status.in_use[1] = pca_status.in_use[3] = 0; pca_status.current = 0; pca_status.sample_rate = SAMPLE_RATE; pca_status.scale = (pca_status.sample_rate << 8) / INTERRUPT_RATE; @@ -198,7 +205,7 @@ pca_stop(void) release_timer0(); release_timer2(); /* reset the buffer */ - pca_status.in_use[0] = pca_status.in_use[1] = 0; + pca_status.in_use[0] = pca_status.in_use[1] = pca_status.in_use[2] = 0; pca_status.index = 0; pca_status.counter = 0; pca_status.current = 0; @@ -241,7 +248,7 @@ pca_wait(void) if (!pca_status.timer_on) return 0; - while (pca_status.in_use[0] || pca_status.in_use[1]) { + while (pca_status.in_use[0] || pca_status.in_use[1] || pca_status.in_use[2]) { x = spltty(); pca_sleep = 1; error = tsleep(&pca_sleep, PZERO|PCATCH, "pca_drain", 0); @@ -300,10 +307,11 @@ pcaopen(dev_t dev, int flags, int fmt, struct proc *p) return EBUSY; } pca_status.buffer = pca_status.buf[0]; - pca_status.in_use[0] = pca_status.in_use[1] = 0; + pca_status.in_use[0] = pca_status.in_use[1] = pca_status.in_use[2] = 0; pca_status.timer_on = 0; pca_status.open = 1; pca_status.processed = 0; + pca_status.non_block = 0; /* block on write */ return 0; } @@ -334,7 +342,9 @@ pcawrite(dev_t dev, struct uio *uio, int flag) return ENXIO; while ((count = min(BUF_SIZE, uio->uio_resid)) > 0) { - if (pca_status.in_use[0] && pca_status.in_use[1]) { + if (pca_status.in_use[0] && pca_status.in_use[1] && pca_status.in_use[2]) { + if(pca_status.non_block) + return EWOULDBLOCK; x = spltty(); pca_sleep = 1; error = tsleep(&pca_sleep, PZERO|PCATCH, "pca_wait", 0); @@ -345,7 +355,11 @@ pcawrite(dev_t dev, struct uio *uio, int flag) return error; } } - which = pca_status.in_use[0] ? 1 : 0; + if(!pca_status.in_use[0]) + which = 0; + else if(!pca_status.in_use[1]) + which = 1; + else which = 2; if (count && !pca_status.in_use[which]) { uiomove(pca_status.buf[which], count, uio); pca_status.processed += count; @@ -428,7 +442,9 @@ pcaioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p) case AUDIO_COMPAT_FLUSH: pca_stop(); return 0; - + case FIONBIO: + pca_status.non_block = (char)(*(int *)data); + return 0; } return ENXIO; } @@ -454,7 +470,8 @@ pcaintr(struct clockframe *frame) if (pca_status.index >= pca_status.in_use[pca_status.current]) { pca_status.index = pca_status.counter = 0; pca_status.in_use[pca_status.current] = 0; - pca_status.current ^= 1; + pca_status.current++; + if(pca_status.current > 2) pca_status.current = 0; pca_status.buffer = pca_status.buf[pca_status.current]; if (pca_sleep) wakeup(&pca_sleep); @@ -476,7 +493,7 @@ pcaselect(dev_t dev, int rw, struct proc *p) switch (rw) { case FWRITE: - if (!pca_status.in_use[0] || !pca_status.in_use[1]) { + if (!pca_status.in_use[0] || !pca_status.in_use[1] || !pca_status.in_use[2]) { splx(s); return(1); }