Audio fixes, round 1 (inspired in large part by openbsd changes by Jacob Mauser) 1284: audio_init_ringbuffer() can be called at times when the pause attribute must not be reset. 1702: respect the pause attribute prior to audiostartr(sc) 1759: The audio_clear() function seems to be called in nearly all the places where the pause attribute should be reset, so add this here. 2313: Poll conditions should match those found elsewhere! Prior to this change, audio_poll was quite problematic for me. 2205: We have an AUDIO_WSEEK ioctl, so why not AUDIO_RSEEK? It's easy, cheap, and consistent. (If no one objects this will be ioctl 36). 2960: the pause attribute defaults to false! (I was not 100% sure about this one, but I have tested it extensively and found no untoward effects) 4050: In audio_resume(), be sure to heed the pause attribute. --- sys/dev/audio.c.orig 2008-05-05 18:33:03.000000000 -0400 +++ sys/dev/audio.c 2008-04-30 23:08:50.000000000 -0400 @@ -1284,7 +1284,6 @@ rp->stamp_last = 0; rp->fstamp = 0; rp->drops = 0; - rp->pause = false; rp->copying = false; rp->needfill = false; rp->mmapped = false; @@ -1702,7 +1701,7 @@ while (uio->uio_resid > 0 && !error) { s = splaudio(); while ((used = audio_stream_get_used(sc->sc_rustream)) <= 0) { - if (!sc->sc_rbus) { + if (!sc->sc_rbus && !sc->sc_rr.pause) { error = audiostartr(sc); if (error) { splx(s); @@ -1759,11 +1758,13 @@ audio_wakeup(&sc->sc_rchan); sc->hw_if->halt_input(sc->hw_hdl); sc->sc_rbus = false; + sc->sc_rr.pause = false; } if (sc->sc_pbus) { audio_wakeup(&sc->sc_wchan); sc->hw_if->halt_output(sc->hw_hdl); sc->sc_pbus = false; + sc->sc_pr.pause = false; } splx(s); } @@ -2205,6 +2206,10 @@ *(u_long *)addr = audio_stream_get_used(sc->sc_pustream); break; + case AUDIO_RSEEK: + *(u_long *)addr = audio_stream_get_used(sc->sc_rustream); + break; + case AUDIO_SETINFO: DPRINTF(("AUDIO_SETINFO mode=0x%x\n", sc->sc_mode)); error = audiosetinfo(sc, (struct audio_info *)addr); @@ -2313,7 +2318,8 @@ * mark. */ if ((!sc->sc_full_duplex && (sc->sc_mode & AUMODE_RECORD)) || - used <= sc->sc_pr.usedlow) + (!(sc->sc_mode & AUMODE_PLAY_ALL) && sc->sc_playdrop > 0) || + (used <= sc->sc_pr.usedlow)) revents |= events & (POLLOUT | POLLWRNORM); } @@ -2468,13 +2474,13 @@ cb->s.bufsize); s = splaudio(); sc->sc_pustream = &cb->s; - if (!sc->sc_pbus) + if (!sc->sc_pbus && !sc->sc_pr.pause) (void)audiostartp(sc); splx(s); } else { s = splaudio(); sc->sc_rustream = &cb->s; - if (!sc->sc_rbus) + if (!sc->sc_rbus && !sc->sc_rr.pause) (void)audiostartr(sc); splx(s); } @@ -2960,10 +2966,12 @@ ai.record.encoding = sc->sc_rparams.encoding; ai.record.channels = sc->sc_rparams.channels; ai.record.precision = sc->sc_rparams.precision; + ai.record.pause = false; ai.play.sample_rate = sc->sc_pparams.sample_rate; ai.play.encoding = sc->sc_pparams.encoding; ai.play.channels = sc->sc_pparams.channels; ai.play.precision = sc->sc_pparams.precision; + ai.play.pause = false; ai.mode = mode; return audiosetinfo(sc, &ai); @@ -4050,9 +4058,9 @@ if (sc->sc_lastinfovalid) audiosetinfo(sc, &sc->sc_lastinfo); audio_mixer_restore(sc); - if (sc->sc_pbus == true) + if ((sc->sc_pbus == true) && !sc->sc_pr.pause) audiostartp(sc); - if (sc->sc_rbus == true) + if ((sc->sc_rbus == true) && !sc->sc_rr.pause) audiostartr(sc); splx(s);