diff options
author | Jason Downs <downsj@cvs.openbsd.org> | 1998-11-03 21:00:12 +0000 |
---|---|---|
committer | Jason Downs <downsj@cvs.openbsd.org> | 1998-11-03 21:00:12 +0000 |
commit | 37cd2221614ee5b8e773155476a3fa2a32d3883d (patch) | |
tree | 9686c429d116ce4ca9e050b9ccf26eb5f4720d62 /sys/dev | |
parent | 992e71fb1eb27d0e5b39f16328cfd34968b8d503 (diff) |
Partial sync with NetBSD, adds new trigger methods.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/audio.c | 343 | ||||
-rw-r--r-- | sys/dev/audio_if.h | 19 | ||||
-rw-r--r-- | sys/dev/audiovar.h | 12 |
3 files changed, 184 insertions, 190 deletions
diff --git a/sys/dev/audio.c b/sys/dev/audio.c index 0cc16f79a12..5ee8c40519a 100644 --- a/sys/dev/audio.c +++ b/sys/dev/audio.c @@ -1,5 +1,5 @@ -/* $OpenBSD: audio.c,v 1.13 1998/07/24 01:59:38 downsj Exp $ */ -/* $NetBSD: audio.c,v 1.71 1997/09/06 01:14:48 augustss Exp $ */ +/* $OpenBSD: audio.c,v 1.14 1998/11/03 21:00:09 downsj Exp $ */ +/* $NetBSD: audio.c,v 1.105 1998/09/27 16:43:56 christos Exp $ */ /* * Copyright (c) 1991-1993 Regents of the University of California. @@ -90,9 +90,11 @@ #ifdef AUDIO_DEBUG #define DPRINTF(x) if (audiodebug) printf x +#define DPRINTFN(n,x) if (audiodebug>(n)) printf x int audiodebug = 0; #else #define DPRINTF(x) +#define DPRINTFN(n,x) #endif #define ROUNDSIZE(x) x &= -16 /* round to nice boundary */ @@ -234,8 +236,8 @@ audioattach(parent, self, aux) hwp->close == 0 || hwp->query_encoding == 0 || hwp->set_params == 0 || - hwp->start_output == 0 || - hwp->start_input == 0 || + (hwp->start_output == 0 && hwp->trigger_output == 0) || + (hwp->start_input == 0 && hwp->trigger_input == 0) || hwp->halt_output == 0 || hwp->halt_input == 0 || hwp->getdev == 0 || @@ -256,12 +258,14 @@ audioattach(parent, self, aux) error = audio_alloc_ring(sc, &sc->sc_pr, AU_RING_SIZE); if (error) { sc->hw_if = 0; + printf("audio: could not allocate play buffer\n"); return; } error = audio_alloc_ring(sc, &sc->sc_rr, AU_RING_SIZE); if (error) { audio_free_ring(sc, &sc->sc_pr); sc->hw_if = 0; + printf("audio: could not allocate record buffer\n"); return; } @@ -298,7 +302,7 @@ audioattach(parent, self, aux) if (mi.type == AUDIO_MIXER_CLASS && strcmp(mi.label.name, AudioCmonitor) == 0) oclass = mi.index; - } + } for(mi.index = 0; ; mi.index++) { if (hwp->query_devinfo(hdlp, &mi) != 0) break; @@ -476,8 +480,8 @@ audio_alloc_ring(sc, r, bufsize) if (hw->round_buffersize) bufsize = hw->round_buffersize(hdl, bufsize); r->bufsize = bufsize; - if (hw->alloc) - r->start = hw->alloc(hdl, r->bufsize, M_DEVBUF, M_WAITOK); + if (hw->allocm) + r->start = hw->allocm(hdl, r->bufsize, M_DEVBUF, M_WAITOK); else r->start = malloc(bufsize, M_DEVBUF, M_WAITOK); if (r->start == 0) @@ -490,8 +494,8 @@ audio_free_ring(sc, r) struct audio_softc *sc; struct audio_ringbuffer *r; { - if (sc->hw_if->free) { - sc->hw_if->free(sc->hw_hdl, r->start, M_DEVBUF); + if (sc->hw_if->freem) { + sc->hw_if->freem(sc->hw_hdl, r->start, M_DEVBUF); } else { free(r->start, M_DEVBUF); } @@ -619,6 +623,7 @@ audiommap(dev, off, prot) dev_t dev; int off, prot; { + switch (AUDIODEV(dev)) { case SOUND_DEVICE: case AUDIO_DEVICE: @@ -689,22 +694,24 @@ audio_initbufs(sc) } #ifdef AUDIO_INTR_TIME +#define double u_long sc->sc_pnintr = 0; sc->sc_pblktime = (u_long)( - (double)sc->sc_pr.blksize * 1e6 / + (double)sc->sc_pr.blksize * 100000 / (double)(sc->sc_pparams.precision / NBBY * sc->sc_pparams.channels * - sc->sc_pparams.sample_rate)); + sc->sc_pparams.sample_rate)) * 10; DPRINTF(("audio: play blktime = %lu for %d\n", sc->sc_pblktime, sc->sc_pr.blksize)); sc->sc_rnintr = 0; sc->sc_rblktime = (u_long)( - (double)sc->sc_rr.blksize * 1e6 / + (double)sc->sc_rr.blksize * 100000 / (double)(sc->sc_rparams.precision / NBBY * sc->sc_rparams.channels * - sc->sc_rparams.sample_rate)); + sc->sc_rparams.sample_rate)) * 10; DPRINTF(("audio: record blktime = %lu for %d\n", sc->sc_rblktime, sc->sc_rr.blksize)); +#undef double #endif return 0; @@ -733,12 +740,14 @@ audio_sleep_timo(chan, label, timo) if (!label) label = "audio"; + DPRINTFN(3, ("audio_sleep_timo: chan=%p, label=%s, timo=%d\n", + chan, label, timo)); *chan = 1; st = tsleep(chan, PWAIT | PCATCH, label, timo); *chan = 0; #ifdef AUDIO_DEBUG if (st != 0) - printf("audio_sleep: %d\n", st); + printf("audio_sleep: woke up st=%d\n", st); #endif return (st); } @@ -756,6 +765,7 @@ static __inline void audio_wakeup(chan) int *chan; { + DPRINTFN(3, ("audio_wakeup: chan=%p, *chan=%d\n", chan, *chan)); if (*chan) { wakeup(chan); *chan = 0; @@ -908,6 +918,8 @@ audio_drain(sc) struct audio_ringbuffer *cb = &sc->sc_pr; int s; + DPRINTF(("audio_drain: enter busy=%d used=%d\n", + sc->sc_pbus, sc->sc_pr.used)); if (sc->sc_pr.mmapped || sc->sc_pr.used <= 0) return 0; if (!sc->sc_pbus) { @@ -974,8 +986,9 @@ audio_close(dev, flags, ifmt, p) DPRINTF(("audio_close: unit=%d\n", unit)); + s = splaudio(); /* Stop recording. */ - if (sc->sc_rbus) { + if ((flags & FREAD) && sc->sc_rbus) { /* * XXX Some drivers (e.g. SB) use the same routine * to halt input and output so don't halt input if @@ -989,25 +1002,29 @@ audio_close(dev, flags, ifmt, p) * Block until output drains, but allow ^C interrupt. */ sc->sc_pr.usedlow = sc->sc_pr.blksize; /* avoid excessive wakeups */ - s = splaudio(); /* * If there is pending output, let it drain (unless * the output is paused). */ - if ((sc->sc_mode & AUMODE_PLAY) && !sc->sc_pr.pause) { - if (!audio_drain(sc) && hw->drain) + if ((flags & FWRITE) && sc->sc_pbus) { + if (!sc->sc_pr.pause && !audio_drain(sc) && hw->drain) (void)hw->drain(sc->hw_hdl); + sc->hw_if->halt_output(sc->hw_hdl); + sc->sc_pbus = 0; } hw->close(sc->hw_hdl); - if (flags & FREAD) + if (flags & FREAD) { sc->sc_open &= ~AUOPEN_READ; - if (flags & FWRITE) + sc->sc_mode &= ~AUMODE_RECORD; + } + if (flags & FWRITE) { sc->sc_open &= ~AUOPEN_WRITE; + sc->sc_mode &= ~(AUMODE_PLAY|AUMODE_PLAY_ALL); + } sc->sc_async_audio = 0; - sc->sc_mode = 0; sc->sc_full_duplex = 0; splx(s); DPRINTF(("audio_close: done\n")); @@ -1030,10 +1047,8 @@ audio_read(dev, uio, ioflag) if (cb->mmapped) return EINVAL; -#ifdef AUDIO_DEBUG - if (audiodebug > 1) - printf("audio_read: cc=%d mode=%d\n", uio->uio_resid, sc->sc_mode); -#endif + DPRINTFN(1,("audio_read: cc=%d mode=%d\n", + uio->uio_resid, sc->sc_mode)); error = 0; /* @@ -1064,10 +1079,7 @@ audio_read(dev, uio, ioflag) if (uio->uio_resid < cc) cc = uio->uio_resid; -#ifdef AUDIO_DEBUG - if (audiodebug > 1) - printf("audio_read: reading in write mode, cc=%d\n", cc); -#endif + DPRINTFN(1, ("audio_read: reading in write mode, cc=%d\n", cc)); error = audio_silence_copyout(sc, cc, uio); sc->sc_wstamp += cc; } @@ -1087,10 +1099,7 @@ audio_read(dev, uio, ioflag) return error; } } -#ifdef AUDIO_DEBUG - if (audiodebug > 2) - printf("audio_read: sleep used=%d\n", cb->used); -#endif + DPRINTFN(2, ("audio_read: sleep used=%d\n", cb->used)); error = audio_sleep(&sc->sc_rchan, "aud_rd"); if (error) { splx(s); @@ -1111,10 +1120,7 @@ audio_read(dev, uio, ioflag) if (sc->sc_rparams.sw_code) sc->sc_rparams.sw_code(sc->hw_hdl, outp, cc); -#ifdef AUDIO_DEBUG - if (audiodebug > 1) - printf("audio_read: outp=%p, cc=%d\n", outp, cc); -#endif + DPRINTFN(1,("audio_read: outp=%p, cc=%d\n", outp, cc)); error = uiomove(outp, cc, uio); used -= cc; outp += cc; @@ -1272,7 +1278,7 @@ audio_write(dev, uio, ioflag) u_char *inp, *einp; int error, s, n, cc, used; - DPRINTF(("audio_write: sc=%p(unit=%d) count=%d used=%d(hi=%d)\n", sc, unit, + DPRINTFN(2, ("audio_write: sc=%p(unit=%d) count=%d used=%d(hi=%d)\n", sc, unit, uio->uio_resid, sc->sc_pr.used, sc->sc_pr.usedhigh)); if (cb->mmapped) @@ -1304,19 +1310,16 @@ audio_write(dev, uio, ioflag) return 0; } -#ifdef AUDIO_DEBUG - if (audiodebug > 1) - printf("audio_write: sr=%ld, enc=%d, prec=%d, chan=%d, sw=%p, fact=%d\n", - sc->sc_pparams.sample_rate, sc->sc_pparams.encoding, - sc->sc_pparams.precision, sc->sc_pparams.channels, - sc->sc_pparams.sw_code, sc->sc_pparams.factor); -#endif + DPRINTFN(1, ("audio_write: sr=%ld, enc=%d, prec=%d, chan=%d, sw=%p, fact=%d\n", + sc->sc_pparams.sample_rate, sc->sc_pparams.encoding, + sc->sc_pparams.precision, sc->sc_pparams.channels, + sc->sc_pparams.sw_code, sc->sc_pparams.factor)); error = 0; while (uio->uio_resid > 0 && !error) { s = splaudio(); while (cb->used >= cb->usedhigh) { - DPRINTF(("audio_write: sleep used=%d lowat=%d hiwat=%d\n", + DPRINTFN(2, ("audio_write: sleep used=%d lowat=%d hiwat=%d\n", cb->used, cb->usedlow, cb->usedhigh)); if (ioflag & IO_NDELAY) { splx(s); @@ -1356,10 +1359,8 @@ audio_write(dev, uio, ioflag) return EINVAL; } #endif -#ifdef AUDIO_DEBUG - if (audiodebug > 1) - printf("audio_write: uiomove cc=%d inp=%p, left=%d\n", cc, inp, uio->uio_resid); -#endif + DPRINTFN(1, ("audio_write: uiomove cc=%d inp=%p, left=%d\n", + cc, inp, uio->uio_resid)); n = uio->uio_resid; error = uiomove(inp, cc, uio); cc = n - uio->uio_resid; /* number of bytes actually moved */ @@ -1377,10 +1378,7 @@ audio_write(dev, uio, ioflag) sc->sc_pparams.sw_code(sc->hw_hdl, inp, cc); /* Adjust count after the expansion. */ cc *= sc->sc_pparams.factor; -#ifdef AUDIO_DEBUG - if (audiodebug > 1) - printf("audio_write: expanded cc=%d\n", cc); -#endif + DPRINTFN(1, ("audio_write: expanded cc=%d\n", cc)); } einp = cb->inp + cc; @@ -1414,10 +1412,7 @@ audio_write(dev, uio, ioflag) error = audiostartp(sc); /* XXX should not clobber error */ splx(s); if (cc) { -#ifdef AUDIO_DEBUG - if (audiodebug > 1) - printf("audio_write: fill %d\n", cc); -#endif + DPRINTFN(1, ("audio_write: fill %d\n", cc)); audio_fill_silence(&sc->sc_pparams, einp, cc); } } @@ -1437,7 +1432,7 @@ audio_ioctl(dev, cmd, addr, flag, p) struct audio_hw_if *hw = sc->hw_if; struct audio_offset *ao; int error = 0, s, offs, fd; - int rbus, pbus; + int rbus, pbus; DPRINTF(("audio_ioctl(%d,'%c',%d)\n", IOCPARM_LEN(cmd), IOCGROUP(cmd), cmd&0xff)); @@ -1458,8 +1453,8 @@ audio_ioctl(dev, cmd, addr, flag, p) case AUDIO_FLUSH: DPRINTF(("AUDIO_FLUSH\n")); - rbus = sc->sc_rbus; - pbus = sc->sc_pbus; + rbus = sc->sc_rbus; + pbus = sc->sc_pbus; audio_clear(sc); s = splaudio(); error = audio_initbufs(sc); @@ -1695,8 +1690,13 @@ audiostartr(sc) sc->sc_rr.start, sc->sc_rr.used, sc->sc_rr.usedhigh, sc->sc_rr.mmapped)); - error = sc->hw_if->start_input(sc->hw_hdl, sc->sc_rr.start, - sc->sc_rr.blksize, audio_rint, (void *)sc); + if (sc->hw_if->trigger_input) + error = sc->hw_if->trigger_input(sc->hw_hdl, sc->sc_rr.start, + sc->sc_rr.end, sc->sc_rr.blksize, + audio_rint, (void *)sc, &sc->sc_rparams); + else + error = sc->hw_if->start_input(sc->hw_hdl, sc->sc_rr.start, + sc->sc_rr.blksize, audio_rint, (void *)sc); if (error) { DPRINTF(("audiostartr failed: %d\n", error)); return error; @@ -1715,15 +1715,21 @@ audiostartp(sc) sc->sc_pr.start, sc->sc_pr.used, sc->sc_pr.usedhigh, sc->sc_pr.mmapped)); - if (sc->sc_pr.used >= sc->sc_pr.blksize || sc->sc_pr.mmapped) { + if (!sc->sc_pr.mmapped && sc->sc_pr.used < sc->sc_pr.blksize) + return 0; + + if (sc->hw_if->trigger_output) + error = sc->hw_if->trigger_output(sc->hw_hdl, sc->sc_pr.start, + sc->sc_pr.end, sc->sc_pr.blksize, + audio_pint, (void *)sc, &sc->sc_pparams); + else error = sc->hw_if->start_output(sc->hw_hdl, sc->sc_pr.outp, - sc->sc_pr.blksize, audio_pint, (void *)sc); - if (error) { - DPRINTF(("audiostartp failed: %d\n", error)); - return error; - } - sc->sc_pbus = 1; + sc->sc_pr.blksize, audio_pint, (void *)sc); + if (error) { + DPRINTF(("audiostartp failed: %d\n", error)); + return error; } + sc->sc_pbus = 1; return 0; } @@ -1731,10 +1737,11 @@ audiostartp(sc) * When the play interrupt routine finds that the write isn't keeping * the buffer filled it will insert silence in the buffer to make up * for this. The part of the buffer that is filled with silence - * is kept track of in a very approcimate way: it starts at sc_sil_start - * and extends sc_sil_count bytes. If the writer doesn't write sc_sil_count - * get to encompass the whole buffer after which no more filling needs - * to be done. When the writer starts again sc_sil_count is set to 0. + * is kept track of in a very approximate way: it starts at sc_sil_start + * and extends sc_sil_count bytes. If there is already silence in + * the requested area nothing is done; so when the whole buffer is + * silent nothing happens. When the writer starts again sc_sil_count + * is set to 0. */ /* XXX * Putting silence into the output buffer should not really be done @@ -1760,27 +1767,19 @@ audio_pint_silence(sc, cb, inp, cc) if (!(s <= p && p < e && s <= q && q <= e)) { if (s <= p) - sc->sc_sil_count = max(sc->sc_sil_count, q - s); -#ifdef AUDIO_DEBUG - if (audiodebug > 2) - printf("audio_pint_silence: fill cc=%d inp=%p, count=%d size=%d\n", - cc, inp, sc->sc_sil_count, (int)(cb->end - cb->start)); -#endif + sc->sc_sil_count = max(sc->sc_sil_count, q-s); + DPRINTFN(5, ("audio_pint_silence: fill cc=%d inp=%p, count=%d size=%d\n", + cc, inp, sc->sc_sil_count, (int)(cb->end - cb->start))); audio_fill_silence(&sc->sc_pparams, inp, cc); } else { -#ifdef AUDIO_DEBUG - if (audiodebug > 2) - printf("audio_pint_silence: already silent cc=%d inp=%p\n", cc, inp); -#endif + DPRINTFN(5, ("audio_pint_silence: already silent cc=%d inp=%p\n", cc, inp)); } } else { sc->sc_sil_start = inp; sc->sc_sil_count = cc; -#ifdef AUDIO_DEBUG - if (audiodebug > 2) - printf("audio_pint_silence: start fill %p %d\n", inp, cc); -#endif + DPRINTFN(5, ("audio_pint_silence: start fill %p %d\n", + inp, cc)); audio_fill_silence(&sc->sc_pparams, inp, cc); } } @@ -1800,23 +1799,24 @@ audio_pint(v) struct audio_ringbuffer *cb = &sc->sc_pr; u_char *inp; int cc, ccr; + int blksize; int error; if (!sc->sc_open) return; /* ignore interrupt if not open */ - cb->outp += cb->blksize; + blksize = cb->blksize; + + cb->outp += blksize; if (cb->outp >= cb->end) cb->outp = cb->start; - cb->stamp += cb->blksize / sc->sc_pparams.factor; + cb->stamp += blksize / sc->sc_pparams.factor; if (cb->mmapped) { -#ifdef AUDIO_DEBUG - if (audiodebug > 2) - printf("audio_pint: mmapped outp=%p cc=%d inp=%p\n", - cb->outp, cb->blksize, cb->inp); -#endif - (void)hw->start_output(sc->hw_hdl, cb->outp, cb->blksize, - audio_pint, (void *)sc); + DPRINTFN(5, ("audio_pint: mmapped outp=%p cc=%d inp=%p\n", + cb->outp, blksize, cb->inp)); + if (!hw->trigger_output) + (void)hw->start_output(sc->hw_hdl, cb->outp, + blksize, audio_pint, (void *)sc); return; } @@ -1829,14 +1829,13 @@ audio_pint(v) if (sc->sc_pnintr) { long lastdelta, totdelta; lastdelta = t - sc->sc_plastintr - sc->sc_pblktime; - if (lastdelta > sc->sc_pblktime / 5) { + if (lastdelta > sc->sc_pblktime / 3) { printf("audio: play interrupt(%d) off relative by %ld us (%lu)\n", sc->sc_pnintr, lastdelta, sc->sc_pblktime); } totdelta = t - sc->sc_pfirstintr - sc->sc_pblktime * sc->sc_pnintr; - if (totdelta > sc->sc_pblktime / 2) { - sc->sc_pnintr++; - printf("audio: play interrupt(%d) off absolute by %ld us (%lu)\n", + if (totdelta > sc->sc_pblktime) { + printf("audio: play interrupt(%d) off absolute by %ld us (%lu) (LOST)\n", sc->sc_pnintr, totdelta, sc->sc_pblktime); sc->sc_pnintr++; /* avoid repeated messages */ } @@ -1847,19 +1846,16 @@ audio_pint(v) } #endif - cb->used -= cb->blksize; - if (cb->used < cb->blksize) { + cb->used -= blksize; + if (cb->used < blksize) { /* we don't have a full block to use */ if (cb->copying) { /* writer is in progress, don't disturb */ cb->needfill = 1; -#ifdef AUDIO_DEBUG - if (audiodebug > 1) - printf("audio_pint: copying in progress\n"); -#endif + DPRINTFN(1, ("audio_pint: copying in progress\n")); } else { inp = cb->inp; - cc = cb->blksize - (inp - cb->start) % cb->blksize; + cc = blksize - (inp - cb->start) % blksize; ccr = cc / sc->sc_pparams.factor; if (cb->pause) cb->pdrops += ccr; @@ -1876,37 +1872,30 @@ audio_pint(v) /* Clear next block so we keep ahead of the DMA. */ if (cb->used + cc < cb->usedhigh) - audio_pint_silence(sc, cb, inp, cb->blksize); + audio_pint_silence(sc, cb, inp, blksize); } } -#ifdef AUDIO_DEBUG - if (audiodebug > 3) - printf("audio_pint: outp=%p cc=%d\n", cb->outp, cb->blksize); -#endif - error = hw->start_output(sc->hw_hdl, cb->outp, cb->blksize, - audio_pint, (void *)sc); - if (error) { - /* XXX does this really help? */ - DPRINTF(("audio_pint restart failed: %d\n", error)); - audio_clear(sc); + DPRINTFN(5, ("audio_pint: outp=%p cc=%d\n", cb->outp, blksize)); + if (!hw->trigger_output) { + error = hw->start_output(sc->hw_hdl, cb->outp, blksize, + audio_pint, (void *)sc); + if (error) { + /* XXX does this really help? */ + DPRINTF(("audio_pint restart failed: %d\n", error)); + audio_clear(sc); + } } -#ifdef AUDIO_DEBUG - if (audiodebug > 3) - printf("audio_pint: mode=%d pause=%d used=%d lowat=%d\n", - sc->sc_mode, cb->pause, cb->used, cb->usedlow); -#endif + DPRINTFN(2, ("audio_pint: mode=%d pause=%d used=%d lowat=%d\n", + sc->sc_mode, cb->pause, cb->used, cb->usedlow)); if ((sc->sc_mode & AUMODE_PLAY) && !cb->pause) { if (cb->used <= cb->usedlow) { audio_wakeup(&sc->sc_wchan); selwakeup(&sc->sc_wsel); if (sc->sc_async_audio) { -#ifdef AUDIO_DEBUG - if (audiodebug > 3) - printf("audio_pint: sending SIGIO %p\n", - sc->sc_async_audio); -#endif + DPRINTFN(3, ("audio_pint: sending SIGIO %p\n", + sc->sc_async_audio)); psignal(sc->sc_async_audio, SIGIO); } } @@ -1933,23 +1922,24 @@ audio_rint(v) struct audio_softc *sc = v; struct audio_hw_if *hw = sc->hw_if; struct audio_ringbuffer *cb = &sc->sc_rr; + int blksize; int error; if (!sc->sc_open) return; /* ignore interrupt if not open */ - cb->inp += cb->blksize; + blksize = cb->blksize; + + cb->inp += blksize; if (cb->inp >= cb->end) cb->inp = cb->start; - cb->stamp += cb->blksize; + cb->stamp += blksize; if (cb->mmapped) { -#ifdef AUDIO_DEBUG - if (audiodebug > 2) - printf("audio_rint: mmapped inp=%p cc=%d\n", - cb->inp, cb->blksize); -#endif - (void)hw->start_input(sc->hw_hdl, cb->inp, cb->blksize, - audio_rint, (void *)sc); + DPRINTFN(2, ("audio_rint: mmapped inp=%p cc=%d\n", + cb->inp, blksize)); + if (!hw->trigger_input) + (void)hw->start_input(sc->hw_hdl, cb->inp, blksize, + audio_rint, (void *)sc); return; } @@ -1980,36 +1970,29 @@ audio_rint(v) } #endif - cb->used += cb->blksize; + cb->used += blksize; if (cb->pause) { -#ifdef AUDIO_DEBUG - if (audiodebug > 1) - printf("audio_rint: pdrops %lu\n", cb->pdrops); -#endif - cb->pdrops += cb->blksize; - cb->outp += cb->blksize; - cb->used -= cb->blksize; - } else if (cb->used + cb->blksize >= cb->usedhigh && !cb->copying) { -#ifdef AUDIO_DEBUG - if (audiodebug > 1) - printf("audio_rint: drops %lu\n", cb->drops); -#endif - cb->drops += cb->blksize; - cb->outp += cb->blksize; - cb->used -= cb->blksize; - } - -#ifdef AUDIO_DEBUG - if (audiodebug > 2) - printf("audio_rint: inp=%p cc=%d used=%d\n", - cb->inp, cb->blksize, cb->used); -#endif - error = hw->start_input(sc->hw_hdl, cb->inp, cb->blksize, - audio_rint, (void *)sc); - if (error) { - /* XXX does this really help? */ - DPRINTF(("audio_rint: restart failed: %d\n", error)); - audio_clear(sc); + DPRINTFN(1, ("audio_rint: pdrops %lu\n", cb->pdrops)); + cb->pdrops += blksize; + cb->outp += blksize; + cb->used -= blksize; + } else if (cb->used + blksize >= cb->usedhigh && !cb->copying) { + DPRINTFN(1, ("audio_rint: drops %lu\n", cb->drops)); + cb->drops += blksize; + cb->outp += blksize; + cb->used -= blksize; + } + + DPRINTFN(2, ("audio_rint: inp=%p cc=%d used=%d\n", + cb->inp, blksize, cb->used)); + if (!hw->trigger_input) { + error = hw->start_input(sc->hw_hdl, cb->inp, blksize, + audio_rint, (void *)sc); + if (error) { + /* XXX does this really help? */ + DPRINTF(("audio_rint: restart failed: %d\n", error)); + audio_clear(sc); + } } audio_wakeup(&sc->sc_rchan); @@ -2342,7 +2325,7 @@ audiosetinfo(sc, ai) { struct audio_prinfo *r = &ai->record, *p = &ai->play; int cleared; - int s, setmode; + int s, setmode, modechange = 0; int error; struct audio_hw_if *hw = sc->hw_if; struct audio_params pp, rp; @@ -2411,7 +2394,7 @@ audiosetinfo(sc, ai) if (nr) { if (!cleared) audio_clear(sc); - cleared = 1; + modechange = cleared = 1; rp.sw_code = 0; rp.factor = 1; setmode |= AUMODE_RECORD; @@ -2419,7 +2402,7 @@ audiosetinfo(sc, ai) if (np) { if (!cleared) audio_clear(sc); - cleared = 1; + modechange = cleared = 1; pp.sw_code = 0; pp.factor = 1; setmode |= AUMODE_PLAY; @@ -2428,7 +2411,7 @@ audiosetinfo(sc, ai) if (ai->mode != ~0) { if (!cleared) audio_clear(sc); - cleared = 1; + modechange = cleared = 1; sc->sc_mode = ai->mode; if (sc->sc_mode & AUMODE_PLAY_ALL) sc->sc_mode |= AUMODE_PLAY; @@ -2437,7 +2420,7 @@ audiosetinfo(sc, ai) sc->sc_mode &= ~AUMODE_RECORD; } - if (setmode) { + if (modechange) { int indep = hw->get_props(sc->hw_hdl) & AUDIO_PROP_INDEPENDENT; if (!indep) { if (setmode == AUMODE_RECORD) @@ -2445,7 +2428,8 @@ audiosetinfo(sc, ai) else if (setmode == AUMODE_PLAY) rp = pp; } - error = hw->set_params(sc->hw_hdl, setmode, sc->sc_mode, &pp, &rp); + error = hw->set_params(sc->hw_hdl, setmode, + sc->sc_mode & (AUMODE_PLAY | AUMODE_RECORD), &pp, &rp); if (error) return (error); if (!indep) { @@ -2461,10 +2445,8 @@ audiosetinfo(sc, ai) rp.precision = pp.precision; } } - if (setmode & AUMODE_RECORD) - sc->sc_rparams = rp; - if (setmode & AUMODE_PLAY) - sc->sc_pparams = pp; + sc->sc_rparams = rp; + sc->sc_pparams = pp; } oldpblksize = sc->sc_pr.blksize; @@ -2537,7 +2519,7 @@ audiosetinfo(sc, ai) if (error) return(error); } - + if (p->pause != (u_char)~0) { sc->sc_pr.pause = p->pause; if (!p->pause && !sc->sc_pbus && (sc->sc_mode & AUMODE_PLAY)) { @@ -2756,7 +2738,7 @@ mixer_remove(sc, p) } /* - * Signal all processes waiting for the mixer. + * Signal all processes waitinf for the mixer. */ static void mixer_signal(sc) @@ -2809,7 +2791,8 @@ mixer_ioctl(dev, cmd, addr, flag, p) mixer_remove(sc, p); /* remove old entry */ if (*(int *)addr) { struct mixer_asyncs *ma; - ma = malloc(sizeof (struct mixer_asyncs), M_DEVBUF, M_WAITOK); + ma = malloc(sizeof (struct mixer_asyncs), + M_DEVBUF, M_WAITOK); ma->next = sc->sc_async_mixer; ma->proc = p; sc->sc_async_mixer = ma; diff --git a/sys/dev/audio_if.h b/sys/dev/audio_if.h index 5d042eb0086..f449117c947 100644 --- a/sys/dev/audio_if.h +++ b/sys/dev/audio_if.h @@ -1,4 +1,4 @@ -/* $OpenBSD: audio_if.h,v 1.6 1998/04/26 21:03:08 provos Exp $ */ +/* $OpenBSD: audio_if.h,v 1.7 1998/11/03 21:00:10 downsj Exp $ */ /* $NetBSD: audio_if.h,v 1.24 1998/01/10 14:07:25 tv Exp $ */ /* @@ -35,6 +35,9 @@ * */ +#ifndef _SYS_DEV_AUDIO_IF_H_ +#define _SYS_DEV_AUDIO_IF_H_ + /* * Generic interface to hardware driver. */ @@ -69,7 +72,8 @@ struct audio_hw_if { * The values in the params struct may be changed (e.g. rounding * to the nearest sample rate.) */ - int (*set_params)__P((void *, int, int, struct audio_params *, struct audio_params *)); + int (*set_params)__P((void *, int, int, struct audio_params *, + struct audio_params *)); /* Hardware may have some say in the blocksize to choose */ int (*round_blocksize)__P((void *, int)); @@ -108,12 +112,17 @@ struct audio_hw_if { int (*query_devinfo)__P((void *, mixer_devinfo_t *)); /* Allocate/free memory for the ring buffer. Usually malloc/free. */ - void *(*alloc)__P((void *, unsigned long, int, int)); - void (*free)__P((void *, void *, int)); + void *(*allocm)__P((void *, unsigned long, int, int)); + void (*freem)__P((void *, void *, int)); unsigned long (*round_buffersize)__P((void *, unsigned long)); int (*mappage)__P((void *, void *, int, int)); int (*get_props)__P((void *)); /* device properties */ + + int (*trigger_output)__P((void *, void *, void *, int, + void (*)(void *), void *, struct audio_params *)); + int (*trigger_input)__P((void *, void *, void *, int, + void (*)(void *), void *, struct audio_params *)); }; struct midi_info { @@ -163,3 +172,5 @@ extern void audio_attach_mi __P((struct audio_hw_if *, struct midi_hw_if *, void #define IPL_AUDIO IPL_BIO /* XXX */ /*#endif*/ +#endif /* _SYS_DEV_AUDIO_IF_H_ */ + diff --git a/sys/dev/audiovar.h b/sys/dev/audiovar.h index f712205c9a2..f3f471e5959 100644 --- a/sys/dev/audiovar.h +++ b/sys/dev/audiovar.h @@ -1,5 +1,5 @@ -/* $OpenBSD: audiovar.h,v 1.5 1998/04/26 21:03:09 provos Exp $ */ -/* $NetBSD: audiovar.h,v 1.17 1997/10/19 07:42:01 augustss Exp $ */ +/* $OpenBSD: audiovar.h,v 1.6 1998/11/03 21:00:11 downsj Exp $ */ +/* $NetBSD: audiovar.h,v 1.18 1998/03/03 09:16:16 augustss Exp $ */ /* * Copyright (c) 1991-1993 Regents of the University of California. @@ -124,7 +124,7 @@ struct audio_softc { struct audio_params sc_pparams; /* play encoding parameters */ struct audio_params sc_rparams; /* record encoding parameters */ - int sc_eof; /* EOF, i.e. zero sixed write, counter */ + int sc_eof; /* EOF, i.e. zero sized write, counter */ u_long sc_wstamp; u_long sc_playdrop; @@ -134,13 +134,13 @@ struct audio_softc { int sc_monitor_port; #ifdef AUDIO_INTR_TIME - u_long sc_pfirstintr; /* first time we saw a xmit interrupt */ + u_long sc_pfirstintr; /* first time we saw a play interrupt */ int sc_pnintr; /* number of interrupts */ - u_long sc_plastintr; /* last time we saw a xmit interrupt */ + u_long sc_plastintr; /* last time we saw a play interrupt */ long sc_pblktime; /* nominal time between interrupts */ u_long sc_rfirstintr; /* first time we saw a rec interrupt */ int sc_rnintr; /* number of interrupts */ - u_long sc_rlastintr; /* last time we saw a xrec interrupt */ + u_long sc_rlastintr; /* last time we saw a rec interrupt */ long sc_rblktime; /* nominal time between interrupts */ #endif }; |