diff options
author | sos <sos@FreeBSD.org> | 1997-09-03 19:08:05 +0000 |
---|---|---|
committer | sos <sos@FreeBSD.org> | 1997-09-03 19:08:05 +0000 |
commit | accad57101d1e89c356813598172b1e7f7a805f4 (patch) | |
tree | 63b0e632b2bed9bdf857785bd87b42e63774833b | |
parent | c202b615480d8a5f27d74865acc45b71c0238393 (diff) | |
download | FreeBSD-src-accad57101d1e89c356813598172b1e7f7a805f4.zip FreeBSD-src-accad57101d1e89c356813598172b1e7f7a805f4.tar.gz |
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 <james@miller.cs.uwm.edu>
-rw-r--r-- | sys/i386/isa/pcaudio.c | 41 |
1 files changed, 29 insertions, 12 deletions
diff --git a/sys/i386/isa/pcaudio.c b/sys/i386/isa/pcaudio.c index c371055..9773a42 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 <sys/fcntl.h> #include <sys/proc.h> #include <sys/kernel.h> +#include <sys/filio.h> #include <machine/clock.h> #include <machine/pcaudioio.h> @@ -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); } |