Module Name: src Committed By: nat Date: Wed Apr 26 11:32:04 UTC 2017
Modified Files: src/sys/dev: audio.c Log Message: Improved blksize calculation. audio_fill_silence instead of audio_pint_silence for the mix ring. Addresses PR kern/52195. To generate a diff of this commit: cvs rdiff -u -r1.327 -r1.328 src/sys/dev/audio.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/audio.c diff -u src/sys/dev/audio.c:1.327 src/sys/dev/audio.c:1.328 --- src/sys/dev/audio.c:1.327 Sat Apr 22 10:37:51 2017 +++ src/sys/dev/audio.c Wed Apr 26 11:32:04 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: audio.c,v 1.327 2017/04/22 10:37:51 nat Exp $ */ +/* $NetBSD: audio.c,v 1.328 2017/04/26 11:32:04 nat Exp $ */ /*- * Copyright (c) 2016 Nathanial Sloss <nathanialsl...@yahoo.com.au> @@ -148,7 +148,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.327 2017/04/22 10:37:51 nat Exp $"); +__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.328 2017/04/26 11:32:04 nat Exp $"); #include "audio.h" #if NAUDIO > 0 @@ -649,8 +649,6 @@ bad_rec: "failed\n", __func__); } - sc->sc_pr.blksize = vc->sc_mpr.blksize; - sc->sc_rr.blksize = vc->sc_mrr.blksize; sc->sc_sih_rd = softint_establish(SOFTINT_SERIAL | SOFTINT_MPSAFE, audio_softintr_rd, sc); sc->sc_sih_wr = softint_establish(SOFTINT_SERIAL | SOFTINT_MPSAFE, @@ -1972,6 +1970,8 @@ audio_initbufs(struct audio_softc *sc, s if (vc == NULL) { chan = SIMPLEQ_FIRST(&sc->sc_audiochan); vc = chan->vc; + sc->sc_pr.blksize = vc->sc_mrr.blksize; + sc->sc_rr.blksize = vc->sc_mrr.blksize; } DPRINTF(("audio_initbufs: mode=0x%x\n", vc->sc_mode)); @@ -1987,6 +1987,8 @@ audio_initbufs(struct audio_softc *sc, s return error; } } + if (vc == SIMPLEQ_FIRST(&sc->sc_audiochan)->vc) + sc->sc_rr.blksize = vc->sc_mrr.blksize; if (audio_can_playback(sc) || (vc->sc_open & AUOPEN_WRITE)) { audio_init_ringbuffer(sc, &vc->sc_mpr, @@ -2000,6 +2002,8 @@ audio_initbufs(struct audio_softc *sc, s return error; } } + if (vc == SIMPLEQ_FIRST(&sc->sc_audiochan)->vc) + sc->sc_pr.blksize = vc->sc_mpr.blksize; #ifdef AUDIO_INTR_TIME #define double u_long @@ -2142,9 +2146,9 @@ audio_open(dev_t dev, struct audio_softc return error; } } + audio_initbufs(sc, NULL); audio_init_ringbuffer(sc, &sc->sc_pr, AUMODE_PLAY); audio_init_ringbuffer(sc, &sc->sc_rr, AUMODE_RECORD); - audio_initbufs(sc, NULL); sc->schedule_wih = false; sc->schedule_rih = false; sc->sc_eof = 0; @@ -2177,8 +2181,8 @@ audio_open(dev_t dev, struct audio_softc mode |= AUMODE_PLAY | AUMODE_PLAY_ALL; } - vc->sc_mrr.blksize = sc->sc_rr.blksize; vc->sc_mpr.blksize = sc->sc_pr.blksize; + vc->sc_mrr.blksize = sc->sc_rr.blksize; /* * Multiplex device: /dev/audio (MU-Law) and /dev/sound (linear) @@ -3583,7 +3587,7 @@ audio_pint(void *v) struct audio_softc *sc; struct audio_chan *chan; struct virtual_channel *vc; - int blksize; + int blksize, cc, used; sc = v; chan = SIMPLEQ_FIRST(&sc->sc_audiochan); @@ -3602,10 +3606,16 @@ audio_pint(void *v) vc->sc_mpr.s.outp, blksize); if (audio_stream_get_used(&sc->sc_pr.s) < blksize) { - audio_fill_silence(&vc->sc_pparams, vc->sc_mpr.s.inp, - vc->sc_mpr.blksize); - vc->sc_mpr.s.inp = audio_stream_add_inp(&vc->sc_mpr.s, - vc->sc_mpr.s.inp, blksize); + used = blksize; + while (used > 0) { + cc = sc->sc_pr.s.end - sc->sc_pr.s.inp; + if (cc > used) + cc = used; + audio_fill_silence(&vc->sc_pparams, vc->sc_mpr.s.inp, cc); + vc->sc_mpr.s.inp = audio_stream_add_inp(&vc->sc_mpr.s, + vc->sc_mpr.s.inp, cc); + used -= cc; + } goto wake_mix; } @@ -3786,8 +3796,10 @@ audio_mix(void *v) inp = cb->s.inp; cc = blksize - (inp - cb->s.start) % blksize; if (sc->sc_writeme == false) - audio_pint_silence(sc, cb, inp, cc, vc); - cb->s.inp = audio_stream_add_inp(&cb->s, cb->s.inp, blksize); + audio_fill_silence(&vc->sc_mpr.s.param, inp, cc); + else + cc = blksize; + cb->s.inp = audio_stream_add_inp(&cb->s, cb->s.inp, cc); mutex_exit(sc->sc_intr_lock); kpreempt_disable(); @@ -4090,9 +4102,6 @@ audio_set_vchan_defaults(struct audio_so if (error == 0) error = audiosetinfo(sc, &ai, true, vc); - sc->sc_pr.blksize = vc->sc_mpr.blksize; - sc->sc_rr.blksize = vc->sc_mrr.blksize; - return error; } @@ -4432,7 +4441,6 @@ audiosetinfo(struct audio_softc *sc, str int error; int np, nr; unsigned int blks; - int oldpblksize, oldrblksize; u_int gain; bool rbus, pbus; bool cleared, modechange, pausechange; @@ -4511,9 +4519,6 @@ audiosetinfo(struct audio_softc *sc, str if (np > 0 && (error = audio_check_params(&pp))) return error; - oldpblksize = vc->sc_mpr.blksize; - oldrblksize = vc->sc_mrr.blksize; - setmode = 0; if (nr > 0) { if (!cleared) { @@ -4698,50 +4703,6 @@ audiosetinfo(struct audio_softc *sc, str pausechange = true; } - if (SPECIFIED(ai->blocksize)) { - int pblksize, rblksize; - - /* Block size specified explicitly. */ - if (ai->blocksize == 0) { - if (!cleared) { - audio_clear_intr_unlocked(sc, vc); - cleared = true; - } - vc->sc_blkset = false; - audio_calc_blksize(sc, AUMODE_RECORD, vc); - audio_calc_blksize(sc, AUMODE_PLAY, vc); - } else { - vc->sc_blkset = true; - /* check whether new blocksize changes actually */ - if (hw->round_blocksize == NULL) { - if (!cleared) { - audio_clear_intr_unlocked(sc, vc); - cleared = true; - } - vc->sc_mpr.blksize = ai->blocksize; - vc->sc_mrr.blksize = ai->blocksize; - } else { - pblksize = hw->round_blocksize(sc->hw_hdl, - ai->blocksize, AUMODE_PLAY, - &vc->sc_mpr.s.param); - rblksize = hw->round_blocksize(sc->hw_hdl, - ai->blocksize, AUMODE_RECORD, - &vc->sc_mrr.s.param); - if ((pblksize != vc->sc_mpr.blksize && - pblksize > sc->sc_pr.blksize) - || (rblksize != vc->sc_mrr.blksize && - rblksize > sc->sc_rr.blksize)) { - if (!cleared) { - audio_clear_intr_unlocked(sc, vc); - cleared = true; - } - vc->sc_mpr.blksize = pblksize; - vc->sc_mrr.blksize = rblksize; - } - } - } - } - if (SPECIFIED(ai->mode)) { if (vc->sc_mode & AUMODE_PLAY) audio_init_play(sc, vc); @@ -4749,6 +4710,22 @@ audiosetinfo(struct audio_softc *sc, str audio_init_record(sc, vc); } + if (vc == SIMPLEQ_FIRST(&sc->sc_audiochan)->vc) { + if (!cleared) { + audio_clear_intr_unlocked(sc, vc); + cleared = true; + } + vc->sc_blkset = false; + audio_calc_blksize(sc, AUMODE_RECORD, vc); + audio_calc_blksize(sc, AUMODE_PLAY, vc); + sc->sc_pr.blksize = vc->sc_mpr.blksize; + sc->sc_rr.blksize = vc->sc_mrr.blksize; + } else { + vc->sc_blkset = true; + vc->sc_mpr.blksize = sc->sc_pr.blksize; + vc->sc_mrr.blksize = sc->sc_rr.blksize; + } + if (hw->commit_settings && sc->sc_opens == 0) { error = hw->commit_settings(sc->hw_hdl); if (error) @@ -4765,9 +4742,7 @@ cleanup: init_error = (pausechange == 1 && reset == 0) ? 0 : audio_initbufs(sc, vc); if (init_error) goto err; - if (vc->sc_mpr.blksize != oldpblksize || - vc->sc_mrr.blksize != oldrblksize || - vc->sc_pustream != oldpus || + if (reset || vc->sc_pustream != oldpus || vc->sc_rustream != oldrus) audio_calcwater(sc, vc); if ((vc->sc_mode & AUMODE_PLAY) &&