Module Name:    src
Committed By:   nat
Date:           Fri Feb  3 20:07:55 UTC 2017

Modified Files:
        src/sys/dev: audio.c

Log Message:
Improved drain function for vc[0].
No need to drain vc[0] for drivers written with start_output.


To generate a diff of this commit:
cvs rdiff -u -r1.298 -r1.299 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.298 src/sys/dev/audio.c:1.299
--- src/sys/dev/audio.c:1.298	Fri Jan 27 05:05:51 2017
+++ src/sys/dev/audio.c	Fri Feb  3 20:07:55 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: audio.c,v 1.298 2017/01/27 05:05:51 nat Exp $	*/
+/*	$NetBSD: audio.c,v 1.299 2017/02/03 20:07:55 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.298 2017/01/27 05:05:51 nat Exp $");
+__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.299 2017/02/03 20:07:55 nat Exp $");
 
 #include "audio.h"
 #if NAUDIO > 0
@@ -1761,7 +1761,7 @@ audio_init_ringbuffer(struct audio_softc
 	rp->copying = false;
 	rp->needfill = false;
 	rp->mmapped = false;
-	memset(rp->s.start, 0, AU_RING_SIZE);
+	memset(rp->s.start, 0, blksize * 2);
 }
 
 int
@@ -2084,9 +2084,11 @@ audio_drain(struct audio_softc *sc, int 
 		return 0;
 
 	used = audio_stream_get_used(&cb->s);
+	if (n == 0)
+		used += audio_stream_get_used(&sc->sc_pr.s);
 	for (i = 0; i < sc->sc_vchan[n]->sc_npfilters; i++)
 		used += audio_stream_get_used(&sc->sc_vchan[n]->sc_pstreams[i]);
-	if (used <= 0)
+	if (used <= 0 || (n == 0 && sc->hw_if->trigger_output == NULL))
 		return 0;
 
 	if (n != 0 && !sc->sc_vchan[n]->sc_pbus) {
@@ -2101,8 +2103,19 @@ audio_drain(struct audio_softc *sc, int 
 		error = audiostartp(sc, n);
 		if (error)
 			return error;
-	} else if (n == 0)
-		goto silence_buffer;
+	} else if (n == 0) {
+		used = cb->blksize * 2;
+		while (used > 0) {
+			cc = sc->sc_pr.s.end - sc->sc_pr.s.inp;
+			if (cc > used)
+				cc = used;
+			audio_fill_silence(&cb->s.param, sc->sc_pr.s.inp, cc);
+			sc->sc_pr.s.inp = audio_stream_add_inp(&sc->sc_pr.s,
+			    sc->sc_pr.s.inp, cc);
+			used -= cc;
+		}
+		mix_write(sc);
+	}
 	/*
 	 * Play until a silence block has been played, then we
 	 * know all has been drained.
@@ -2116,6 +2129,9 @@ audio_drain(struct audio_softc *sc, int 
 	}
 #endif
 	sc->sc_vchan[n]->sc_draining = true;
+
+	i = 0;
+drain_again:
 	drops = cb->drops;
 	error = 0;
 	while (cb->drops == drops && !error) {
@@ -2128,21 +2144,12 @@ audio_drain(struct audio_softc *sc, int 
 		if (sc->sc_dying)
 			error = EIO;
 	}
+	i++;
+	if (n == 0 && i < 2)
+		goto drain_again;
 
-silence_buffer:
-
-	used = 0;
-	if (sc->sc_opens == 1) {
-		cb = &sc->sc_pr;
-		cc = cb->blksize;
-		
-		while (used < cb->s.bufsize) {
-			memset(sc->sc_pr.s.start, 0, cc);
-			mix_write(sc);
-			used += cc;
-		}
-	}
 	sc->sc_vchan[n]->sc_draining = false;
+
 	return error;
 }
 
@@ -3368,18 +3375,30 @@ audio_pint(void *v)
 {
 	struct audio_softc *sc;
 	struct virtual_channel *vc;
+	int blksize, i, used;
 
 	sc = v;
 	vc = sc->sc_vchan[0];
+	blksize = vc->sc_mpr.blksize;
 
 	if (sc->sc_dying == true)
 		return;
 
-	if (audio_stream_get_used(&sc->sc_pr.s) < vc->sc_mpr.blksize)
+	used = audio_stream_get_used(&vc->sc_mpr.s);
+	for (i = 0; i < vc->sc_npfilters; i++)
+		used += audio_stream_get_used(&vc->sc_pstreams[i]);
+
+	if (audio_stream_get_used(&sc->sc_pr.s) <blksize)
 		goto wake_mix;
 
+	if (vc->sc_draining == true && used <= 0) {
+		vc->sc_mpr.drops += blksize;
+		cv_broadcast(&sc->sc_wchan);
+	}
+
 	vc->sc_mpr.s.outp = audio_stream_add_outp(&vc->sc_mpr.s,
-	    vc->sc_mpr.s.outp, vc->sc_mpr.blksize);
+	    vc->sc_mpr.s.outp, blksize);
+
 	mix_write(sc);
 
 wake_mix:
@@ -5767,7 +5786,6 @@ audio_play_thread(void *v)
 
 		audio_mix(sc);
 	}
-
 }
 
 void

Reply via email to